�ɲɾ�����ӯ�����һ��ˣ��������С���˴��ͣ�������P���ҹ��ñ˽��ά�Բ��������˸߸ԣ�������ơ��ҹ��ñ�����ά�Բ���ˡ���˳^�ӣ������ӡ� ���ͯj�ӣ��ƺ���ӣ� ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!usr/bin/c++000075500004651670152525154330006453 0ustar00ELF>@J@8 @#"@@@!! `$`$0`$08 88282    DD`$`$0`$0Std Ptd88QtdRtd`$`$0`$0/lib64/ld-linux-x86-64.so.2GNUGNUGNU3llAuoI_UnP0`(~ju>[ĉݣkfUaN<Ĺ@9M> q 2 >aaJ7@'Tu} `QfZMg,C[' zn[Th ."YZFe@*vfDsl%|JE?\6 `1"p"`2%P1 S2}*}'!2!282n0 #n} 220 libm.so.6_ITM_deregisterTMCloneTable__gmon_start___ITM_registerTMCloneTablelibc.so.6fflushstrcpyreaddirexecvsetlocalefopenstrsignalstrncmpstrrchrpipengettextfileno_unlockeddl_iterate_phdrclosedirftellstrncpymbstowcs__stack_chk_fail__lxstatunlinkputcharpthread_mutex_lockreallocabortstdin_exitvsprintfmemchrgetpidkillstrdupsbrkgmtimestrtokstrtolisattymmapfeoffgetcfgetscallocstrlenungetc__cxa_atexitfread_unlockedmemsetstrstrstrcspn__errno_locationfseekmemcmpgetpagesizedgettextasctimedup2unsetenvpthread_mutex_unlockputenvwcswidthstdoutfputcfputsstrnlenmemcpyfclosestrtoulmallocstrcatstrcasecmprealpathremove__uflownl_langinfoopendir__ctype_b_locgetenvsscanf_obstack_allocated_pstderrioctlmunmap_obstack_begin_1wait4_obstack_newchunkreadlinksetrlimitexecvpfreopenstrncasecmp__fxstat_obstack_memory_usedfwritefreadiconv_closegettimeofdaywaitpidstrverscmplocaltimestrchrvforkiconvmkstempsfdopenqsorticonv_opensleep__ctype_tolower_locobstack_alloc_failed_handler__cxa_finalizefcntl__fsetlocking__xstatgetrlimitmemmove_obstack_beginbindtextdomainaccessfwrite_unlockedstrcmpstrerror__libc_start_mainferrorstpcpyvfprintfsnprintf__overflow_obstack_freefputs_unlocked__environld-linux-x86-64.so.2__tls_get_addrGLIBC_2.3GLIBC_2.14GLIBC_2.4GLIBC_2.11GLIBC_2.2.5__pthread_key_createpthread_once ii ;PEii ;ii PZui e`$0h$0p$0x$0$0$0$00$0`$0$0$0K $0K $0&K $0K %0*K %0.K %0=K (%0.K @%0@K H%0.K `%0EK h%0IK %0NK %0IK %0SK %0IK %0XK %0IK %0\K %0IK &0aK &0IK &0dK (&0IK @&0iK H&0IK `&0mK h&0rK &0wK &0rK &0|K &0K &0K &0K &0K &0K '0K '0K '0K ('0K @'0K H'0K `'0K h'0K '0K '0K '0K '0K '0K '0K '0K '0K (0K (0K (0K ((0K @(0K H(0K `(0K h(0K (0K (0K (0K (0K (0K (0K (04k(0K )0K )0z )02 ()0| @)0 H)0E `)0E h)0 } )0K )0K )0K )0 )0K )0K )0K )0 *0L *0L *0L (*0L @*0L H*0P `*0EK h*0L *0XK *0L *0NK *0L *0SK *0L *0\K *0L +0aK +0L +0dK (+0L @+0$L H+0E `+0'L h+0E +0,L +0E +00L +0E +05L +0E +0:L +0E ,0?L ,0E ,0DL (,0E @,0E H,0 P,0HL `,0L h,0 p,0HL ,0iK ,0]L ,0]L ,0 ,0K ,0mL ,0K ,0mL -0K -0mL -0K (-0mL @-0K H-0mL `-0mL h-0( -0|K -0|L -0K -0|L -0K -0|L -0|L -0 .0K .0L .0K (.0L @.0K H.0L `.0K h.0L .0L .0 .0K .0L .0K .0L .0K .0L /0K /0L /0L (/0 @/0L H/0 /0D /0 /0L /0 /0L /0` /0C /0 /0L /0 /0L /0` /0 /0L /0D /0 00D 00ȍ 00C (00L 000D 800L @00D H00L P00D X00L `00A h00M 00A 00A 00A 00 000 00ƴ 00p 00ٴ 10 10 010( @10 X10h h10 10 10" 10@ 10 10 10 10 20= 20p 020Z H20 X20 p20@ 20 20 20u 20 20 20 20 300 30 830 H30׵ `30 p30 308 30 30p 30 30 301 40 40D (408 840U P40 `40j x40 40| 400 40p 40 40 40 50 50@ (50 @50x P50 h50 x508 50` 50 50 50׶ 50@ 50 60 60 060 @60 X60H h60$ 60 60? 60 60P 60 60a 60H 70p 70 070 H70 X70 p70 70 70X 70 70 70η 70 70 808 80 880p H80 `80 p80( 80H 80" 80 804 80 80? 90@ 90 (90 890O P90 `90h x90 90 90 90 90 90 90 :0ø :0` (:0ܸ @:0 P:0 h:00 x:0 :0 :0 :0X :0& :0 :0 ;0( ;0> 0;0 @;0\ X;0@ h;0p ;0 ;0 ;0 ;0 ;0 ;0 ;0` <0ʹ <0 0<0ع H<0 X<0 p<0@ <0 <0 <0 <0 <0 <0x <0 =0 =0 8=0 H=03 `=08 p=0 =0 =0 =0H =0 =0 =08 >0X >0L (>0 8>0h P>0 `>0w x>0H >0 >0 >0 >0 >0 >0P ?0Ѻ ?0 (?0 @?0P P?0 h?0 x?0 ?0 ?0` ?0 ?0+ ?0 ?0I @0 @0` 0@0 @@0} X@0 h@0 @0( @0 @0h @0ƻ @0 @0޻ @0 A0 A0 0A0 HA0 XA0 pA0@ A02 A0p A0B A0 A0 A0@ A0 B0 B0] 8B08 HB0s `B0 pB0 B0 B0 B0@ B0 B0Ƽ B0ܼ C0 C0 (C0 8C0x PC0 `C0. xC0 C0L C0 C0` C08 C0y C0 D0 D0 (D0 @D00 PD0 hD0X xD0 D0 D0 D0 D0X D0 D0 E0 E0ѽ 0E0h @E0 XE0 hE0 E0 E0 E0 E02 E0 E0P E0p F0 F0 0F0P HF0 XF0i pF0H F0 F0 F0 F0 F08 F0X F0 G0 G0¾ 8G0 HG0ھ `G0 pG0 G0@ G0 G0x G0$ G0 G0> H0 H0 (H0 8H0H PH0p `H0T xH0 H0i H0x H0 H0 H0 H0@ I0 I0 (I0ʿ @I0 PI0ܿ hI0 xI0 I0 I0 I08 I0" I0 I01 J0 J0C 0J0@ @J0 XJ0 hJ0U J0 J0h J0@ J0~ J0 J0 J0 K0 K0 0K0 HK0 XK0 pK00 K0 K0x K0 K0 K0# K0 K0< L0@ L0O 8L0Z HL0x `L0 pL0 L0 L0 L0 L0 L0 L0 M0( M0 (M0X 8M0 PM0 `M0( xM0X M0 M0 M0 M0( M0 M0 N03 N0 (N0M @N0 PN0c hN0 xN0} N0p N0 N0 N0 N0 N0 O0P O0 2O0 0O0 @O0 XO0 hO0 O0` O0 O0 O0h O0 O0 O0( P0P P0p 0P00 HP0 XP0J pP0 P0` P0X P0w P0 P0 P0 P0 Q08 `Q0 pQ0 Q0:6 Q0 Q0 Q0( Q0>v Q0X R0/ R08 `R0C R0F R0J R0B R0 S0G S0S @S0Y `S0d S0s S0G S0N S0 T0< T0L@ @T0 `T0N T0N T0 T0 T0{X U0 U0h @U0 `U0 U0 U0 U0 U0V V0i @V0` HV00 PV0 XV0 `V0 V02 V02 V02 V0 2 V0#2 V0)2 V0,2 V0 W022 W0)2 W0;2 0W0 @W0F2 PW0 `W0T2 pW0 W0_2 W0 W0m2 W0FC W0 W0m2 W02 W0 W0w2 W02 X02 X02 X02 (X0FC 0X02 @X02 PX02 `X02 pX02 X02 X0 2 X02 X0 2 X0 5 Y0%5 Y045 Y0;5 @Z0F5 PZ0O5 Z0k5 Z0O5 [0u5 `[05 [05 \05 \05 \05 \05 @]05 P]05 ]05 ^05 `^06 ^0 6 _06 _0!6 _0)6 @`026 `0C6 a0S6 `a0d6 a0q6 b06 b06 b0WC b06 @c06 Hc08 c06 c06 d06 d06 `d06 pd06 d06 d02 e07 0e07 e037 e07 e0M7 e07 @f0h7 Pf07 f0}7 g07 `g07 g07 h07 h07 h0 8 @i0*8 i0A8 i06 j0L8 `j0W8 j0c8 k0w8 k08 k08 @l08 l08 m08 `m08 m09 n09 n0'9 n06 n009 @o0>9 Po06 o0H9 o0У p0P9 `p0Y9 p0k9 q0v9 q09 q09 @r09 r09 s09 `s09 s09 t09 t08 t09 @u0 : u0: v08: `v0J: v0\: w0o: w0: w0` @x0: x0: y0: `y0: y0: z0: z0: z0: @{0: {0: |0^C |0: `|0; |0; }0+; }09; }0K; @~0W; P~05 ~0h; ~05 0z; `0; 0MC 0; 006 0; 06 0; 0 0O5 @0; 0#K 0; 0; 0 `0; h00 p05 0fG 0C (0 007 0; 0 0; 0 07 @0; H0X 0C 0; 0; `0< h0 p06 0< ȅ0 Ѕ06 0< (0 0!< 0 0%< 0@ 06 @0*< H0p 0.< 0 0 02< 0 0 `06< 02 Ȉ0 09< (0@ 0@< 0 0D< 0 @0H< H0 0K< 0N< `0R< 0V< 0Y< 0\< 0_< @0e< 0l< 0s< `0{< 0< 0< (0< 005 02 0 0< @0< H0@ 0< 0 0< 0 `0< h0X 0< ȑ0 0 (0 0< 00 0< 0h @0< H0 `0/U h0` 0 = 0ث 0= 0 = `0>= h08 0X= Ȕ0Ь 0e= (0n= 0= 0 0= 0 @0= H0 0= 08 0= 08 `0= h0h 0= ȗ0 0> (0 0> 0@ 0$> 0p @08> `0E> h0` 0I> 0 0W> 0 `0f> h0X 0 Ț0 0w> (0 0> 0@ 0> @0> H0 0> 0 0> 08 `0> 0> ȝ0 0> (0ز 0 ? 0 0? 0h @0)? H0h 0=? 0 0R? 0س `0^? h0 0aF0F0l? Ƞ0 0{? (0@ 0? 0p 0? 0 @0? H0 0? 0( 0? 0p `0? h0? 0? ȣ0ص 0@ (0 0@ 0P 0,@ 0 @0?@ H0 0Q@ 0 0e@ 0( `0k@ h0X 0@ Ȧ0@ 0@ (0 0@ 0ȷ 0@ 0 @0@ H08 0A 0 0A 0ȸ `0(A h0 0:A ȩ0` 0RA (0 0oA 0ع 0A 0 @0A H0H 0A 0 0A 0 `0A h0 0A Ȭ0P 0A (0 0B 0Ȼ 0B 0 @0B H00 0-B 05B 0` 0 0SB `02 h0ؼ 0qB ȯ0 0B (0( 0B 0X 0B 0 @0B H0 0B 0 0B 0H 0aF(0F`0B h0 0B Ȳ0Ⱦ 0C (0 0C 0H 0aF0F0&C 0ȿ @09C H00 0KC 0p 0_C 0 0aF(0F`0sC h0 0C ȵ0` 0C (0 0C 0H 0C 0 @0C H0 0C 0p 0C 0 `0 D h0 0"D ȸ0 0(D (0( 09D 0X 0ND 0 @0cD H0 0nD 0 Ⱥ0F0D 0 `0 h0 0D Ȼ0P 0D (0 0D 0 0D @0D H0 0D 0@ 0E 0 `0"E h0 0+E Ⱦ0 01[ H>1` >1\ >1 ?11\ ?1^ (?1E\ `?1K\ h?1 ?1`\ ?1( @1` (@1 @1}\ @1 @1\ @1 @A1\ HA1p A1 A1 B1\ B1\ `B1\ hB18 B1] B1 C1] (C1 C1+] C1 C11] C1 @D19] HD1H D1I] D1 E1^] E1 `E1j] E1G E1 F1}] (F1 F1] F1P F1] F1x @G1] HG1 G1G G1 H1] H1P `H1] hH1] H1^ H1 I1$^ (I1 I1<^ I10 I1M^ I1^^ @J1v^ J1^ J1` K1^ K18 `K1 hK1 K1 K1( L1^ (L1X L1^ L1 L1^ L1 @M1_ HM1( M1!_ M1x N1+_ N1 `N1>_ xN1p N1O_ N1\_ O1w_ (O1 O1_ O1X O1_ O1 @P1_ HP1 P1_ P1 Q1_ Q1 `Q1_ hQ1 Q1` Q1p R1` (R1 ` R1<` R1H` R1 @S1Z` HS1 S1m` S1(! T1` T1X! `T1` hT1! T1` T1! U1` (U1 " U1` U1X" U1` U1" @V1` HV18 V1` V1" W1` W1# `W1a hW1`# W1'a W1# X16a (X1# X1Ba X18$ X1Na X1h$ @Y1ba HY1$ Y1za Y1$ Z1a Z1(% `Z1a hZ1`% Z1a Z1% [1a ([1% [1a [1% [1a [1& @\1a H\1H& \1 b \1& ]1b ]1' `]1b h]1P' ]1)b ]12b ^1Ib (^1' ^1[b ^1 ( ^1jb ^1@( @_1xb H_1p( _1b _1( `1b `1( ``1b h`1) `1b `1X) a1b (a1) a1b a1) a1b a1* @b1c Hb1h* b1c b1* c1*c c1* `c19c hc10+ c1Gc c1`+ d1Tc (d1+ d1oc d1+ d1zc d1(, @e1c He1X, e1c e1p f1c f1, `f1c f1c g1c (g1, g1c g1p g1c g10- @h1d Hh1T Xh1p h1d h1d i1:d i1X- `i1Jd hi1- i1[d i1- j1od (j1. j1d j1P. j1d j1. @k1d Hk1d k1d k1. l1d l1/ `l1 e hl1X/ l1e l1/ m1)e (m1/ m1;e m10 m1Ke m1X0 @n1Xe Hn10 n1ae n10 o1re o1@1 `o11 ho11 o1e p1e (p11 p1e p1@2 p1e p12 @q1e Hq12 q1e q1H3 r13 r13 `r1 4 hr1P4 r1e r14 s1f (s14 s1,f s14 s1Ff s15 @t1Sf Ht1P5 t1\f t18 u1of u15 `u1~f hu15 u1f u16 v1f (v1@6 v1f v1 v1f v1p6 @w1f Hw16 w1f w16 x1f x16 `x1f hx107 x1g x1h7 y1g (y1 y1"g y17 y1,g y17 @z1=g Hz18 z1Rg z1P8 {1fg {18 `{1tg h{18 {1g {19 |1g (|189 |19 |19 |1: |1: @}1g H}1; }1g }1< ~1g ~18< `~1g ~1g ~1x< 1 h (1< 1!h 1< 16h 1(= @1Nh X1p 1Zh 1p= 1sh 1= `1h h1> 1h 1h 1h 1> 1h 1h @1h H1> 1i 1? 1i 1? `1&i h1X@ 13i Ȅ1 1Bi (1@ 1Ui 1@ 1ji 18 @1zi H1i 1i 1X@ 1i 1@ `1i h1A 1i ȇ18A 1i (1XA 1j 1A 1j 1A @1(j H1 B 15j 1XB 1Fj 1B `1Mj h1B 1Vj Ȋ1(C 1lj (1pC 1j 1C 1j 1D @1j H1hD 1j 1D 1j 1D `1j h1@E 1j ȍ1E 1k (1E 1k 1E 1/k 1 F @1Ak H1`F 1Wk 1F 1ik 1G `1zk h1XG 1k Ȑ1G 1k (1G 1k 1H 1k 1p @1k X1p 1k 1p 1k 1p `1 l x1p 1l ȓ1HH 1*l (1H 1=l 1H 1Ll 1I @1\l H1PI 1rl 1l 1p `1l h1I 1l Ȗ1I 1l (1 J 1l 1J 1l 1J @1l H1J 1m 18K 1m 1K `1*m h1K 1;m ș1L 1Jm (1XL 01L 1Um 1L 1jm 1tm @1m H1M 1m 10M 1m 1`M `1m h1M 1m Ȝ1M 1m (1M 1m 1 1m 10N @1n H1`N 1n 18 1'n 1N `16n h1N 1Dn ȟ1N 1Sn (1fn 1n 1@O 1n 1pO @1n 1n 1O 1n 1n `1n h1O 1n Ȣ1P 1o (1@P 1o 1pP 11o 1P @17o H1Q 1=o 1hQ 1Po 1Q `1Vo h1Q 1do ȥ1no 1o (18R 1o 18R 1o 1R @1o H1R 1o 1R 1o 1 S `1p h1S 1p Ȩ1S 1#p (1S 16p 1 T 1Ep 1PT @1Zp H1T 1ip 1T 1|p 1@U `1p h1U 1p ȫ1U 1p (1 V 1p 1pV 1p 1V @1p H1(W 1p 1XW 1q `1q h1W 1+q Ȯ1W 19q (1W 1Jq 1 X 1[q 1HX @1kq H1pX 1|q 1X 1q 1X `1q h1X 1q ȱ1Y 1q (1XY 1q 1Y 1q 1Y @1q H1Z 1r 1HZ 1 r 1xZ `1r h1 1'r ȴ1Z 1:r (1Z 1Kr 1[ 1X[ 1x[ @1gr H1[ 1{r 1[ 1r 1(\ `1r h1\ 1r ȷ1\ 1r (1] 1r 1X] 1r 18 @1] H1] 1r 1s 1s 1(^ `1,s h1h^ 1^ 13s (1^ 1Hs 1^ 1[s 1(_ @1os H1p_ 1_ 1_ 1s 1s `1@` h1`` 1s Ƚ1` 1s (1` 1s 1a 1s 1(a @1 t H1`a 1t 1a 14t 1a `1At h1a 1]t 10b 1ot (1Xb 1t 1b 1t 1b @1t H1c 1t 1pc 1t 1c `1t h1d 1u 18 1+u (1Pd 1=u 1d 1Nu 1d @1`u H1e 1tu 1Pe 1u 18 `1u h1e 1e 1f 1Hf (1pf 1u 1f 1u 1f @1u H1g 1u 1Pg 1u 1g `1v h1h 1v 1Ph 1"v (1h 10v 1i 1Gv 1Hi @1Sv H1pi 1dv 1i 1wv 1i `1v h1j 1v 1hj 1v (1j 1v 1(k 1v 1Xk @1v H1v 1w 1k 1$w 1k `12w h1k 1Ew 1p 1Pw (1l 1_w 1Xl 1lw 1l @1zw H1l 1w 1m 1 1 1w 1Xm `1w h1m 1w 1w (1 n 1w 1pn 1w 1n @1 x H1n 1#x 1 o 1>x 1xo `1Wx h1o 1fx 1p 1tx (1@p 1|x 1xp 1x 1x @1x H18 1x 1p 1x 1p `1x h1Pq 1x 1p 1y (1q 1$y 1q 1i 1` 18y 1q @1My H1Hr 1]y 1r 1ky 1r `1vy 1aF1F1y 1s 1y 1y 1`s 1y @1y H1s 1y 1t 1z 1(t `1z x1p 1)z 1pt 18z (1t 1pG 1t 1Mz 1(u @1cz H1Xu 1pz 1u 1z 1v `1z 1z 1Hv 1z (1v 1z 1@w 1z 1pw @1z H1w 1z 1w 1 { 1(x `1{ h1Px 1{ 18 1<{ (1xx 1Q{ 1x 1b{ 18 @1t{ H1x 1{ 1y 1{ 1@y `1{ h1`y 1{ 1y 1{ (1y 1y 1z 1{ 1Hz @1{ H1pz 1{ 1 1| 1z `1&| h1z 1:| 1X@ 1M| (1{ 1b| 1@{ 1x| 1h{ @1| H1{ 1| 1{ 1| 1P| `1| h1| 1| 1| 1| (1| 1| 18 1| 1} @1} H1P} 1} 1x} 1%} 1} `11} h1} 1<} 18 1M} (18 1d} 1~ 1}} 1} @1} H1@~ 1} 1 1} 1x~ `1} h18 1} 1~ 1~ (1~ 1 ~ 1  1/~ 1P @1@~ H1 1S~ 1 1b~ 18 `1~~ h1 1~ 1( 1~ (1p 1~ 1~ 1~ 1 @1~ H1Ѐ 1  1 1' 18 `14 h1p 1B 1 1O 1c 1r 1 1 @1 H1@ 1 1h 1 1 `1 h1 1 1 1 1p 1 (1 1 1 1( @1! H1p 18 1 1F 1 `1L h1T x1p 1X 1T 1p 2h (28 2y 2h 2 2 @2 H2ȅ 2 2 2 28 `2 h28 2 2` 2р (2Ȇ 2 2 2 2X @2 H2 2 2؇ 2 2T 2p `2 h28 2 2 21 (20 2)2 2 2= 2C @2P H2 2a 2 2v 28 2( `2} h28 x2( 2 28 2( 2 ( 28 8 2( 2 2H 2 2 @ 2 H 2ȉ 2 2 2  20 ` 2Ł h 2h 2ԁ 2 2 ( 2 2 2P 2 2x @ 2#2 2 2 2 2 `2 h2 2 2P 2. (2 26 2 2? 2 @2U H2( 2 C 2` 2d 2 `2 2~ 2 2 (2 2 2H 2 2 @2 H2 2 2 2 27 `26 h28 p26 2D 2p 2D (2 26 2 26 2YG 2H @2D H2 2 2А 27 2D 2 27 `2D h2P p27 2 2 2 (2 2Ԃ 2؂ 2F @2 2 2 2& 2+ `2E h2J 2 2( 2d (2P 2m 2r 2 2 @2 H2 2 2ǃ 2 2 `2 h2 2 2` 2 (2 2Ű 2 2 2Г @2, H2: 2X 2 2g  20 ` 2z h 2` 2 2 !2 (!2 !2 !2 !2 !2 @"2ل H"2 "2˯ "2 #2ܯ #2x `#2 h#2 #2 #20 $2 ($2X $2 $2 $2dz $2h @%2 H%2 %2M %2p &2 &2 `&22 h&2p &2 &2 '2B ('2h '2h '2 '2a '2p @(2 H(2 (2' (2x )2IJ )2 `)2 h)28 )2 )2$ *2Q (*2 *2 *2 *2: *20 @+2I H+2` +2` +2Ȟ ,2m ,2( `,2 h,2` ,2 ,2s -20 (-2 -2 -2 -2 -2 @.2 H.2 .2o .28 /2Å /2p `/2؅ /2i /2 02 (02 02 02H 02 02 @12- H12 12 120 22 22x `22* h22 22: 22Т 32| (32 32D 32X 32W 32 42;< 42y @42ְ H42У 42d 42 52m 528 `52x h52 52 52 62 (62p 622 62 62 62ؤ @72 H72 72 720 82ۆ 82h `82 h82 82 82 92% (920 92X 92x 92< 92ئ :2K :2Q @:2U H:2H :2m :2 ;2 ;2 `;2 h;2҇ ;2 ;2 <2 (<2 <2 <20 <2 <2p @=2 H=2 =2 =2 >2 >2 `>2, h>2H >2 >2 ?2 (?2% ?2B ?2 ?2Q ?2X @@2 H@2 @2l A2 A2 `A2 A2 B2ʈ B2؈ B20 B2 B2 @C2 HC2ت C2 C2 D2 D28 `D2 hD2h D2̮ D2 E2 8E2( E2b E2Ы E2G E2 @F2 HF2@ F2E F2p F2{ F2U G2Y G2Ь `G2p hG28 G2 G2p H2 (H2 H2 H2Э H2X H2 @I2T HI2@ I2 I2 J2 J2x `J2 hJ2 J2ʼn J2 K2Չ (K2( K2 K2P K2 K2 @L2C HL2 L2 L2 M2 M2 `M2 hM2@ M2 M2 N2 (N2ذ N2 N2- N2 N2 @O2 HO2X O2E O2 P22 P2б `P2O hP2 P2 P2x Q2 (Q2 Q2Z Q2в Q2V Q2] @R2t HR2 R2E R2` S2 S2 `S2 hS2г S2 S2 T2X (T2x T2Ɗ T2 T2ߊ T2 @U2 HU2 U2 U2 V2 V2x `V2$ hV2 V23 V2ص W2I (W2 W2V W2^ W2{ W2 @X2 HX2@ X2 X2 Y2‹ Y2x `Y2 hY2 Y2Ջ Y2 Z2{ (Z28 Z2 Z2 Z2@ Z2x @[2 H[2 [2ñ [2 \2 \2! `\2ڱ h\2ط \2? ]28 ]28 ]2B ]2 @^2J H^2Q ^2h _2w `_2 h_2P _2 _2 `2 (`2 `2C `2( `26 `2 `2 @a2Z9 a2l9 b2w9 b2P `b2Ì b29 b2 c29 c2nj c29 @d29 d29 e2 : `e2: e29: f2Ό (f2 f2]: f2p: @g2: g2 h2: `h2 h2iG h2 i2 i2 i2 i20 @j2" j2: k2% `k2: hk22 k2K l2: l2: l2: @m2Z m2j n2y n2X `n2 n2 o2 o2 o2э @p2 p2 q2: q2 `q2 hq2к q2 q2 r2 (r2H r2% r2p r20 r2 @s2; Hs2 s2F s2 t2Q t2 `t2\ ht2к t2g t2h u2p (u2 u2y u2 u2 u2ؼ @v2 Hv2 v2 v2 w2 w2( `w2 hw2P w2 w2x x2 (x2 x2Ŏ x2ؽ x2Ҏ x2 @y2ݎ Hy2H y2 y2p z2 z2 `z2 hz2 z2 z2( {2 ({2h {2# {2 {20 {2 @|2= H|2 |2J |28 }2W }2 `}2d h}2 }2o }2 ~2z (~2 ~2 ~2@ ~2 ~2h @2 H2h 2 2 2 2 `2 h2 2Ώ Ȁ2 2 (2( 2 28 2 2h @2 H2 2* 2 2< 2h `2: 2H 2; 2K 2R @2b 2,; 2:; 2 `2L; h2 2r 2u (2 2| 2 2NC 2( @2 H2 2yE 2 `2 2sK ȉ2 Љ2 ؉2 2$K 2JK 2K 2K 2Ɛ 2ʐ 2ϐ 2H 022@26H2=P2 `22p2Dx2K2 2`22 F 2R2 22Њ2Y؊2`222g2n2 2202 82. H2P P2 2`25 h2< 222C 2J 222Q ȋ2X 2`22_ 2 2 2 2 2u(2|82 @22P2X2`2֐ p2`2222 2222Ȍ2 Ќ22222 2`222 2@ 022@2H2P2 `22p2x22 2`2222' 2 2Ѝ2؍22 222 2 2 2202 82 @2h P2@2`2 h2$ x2 222+ 22 2> 2229 Ȏ2@ ؎2 2@22G 2N 2X 22 2U (2\ 82 @22P2c X2j `2P p222q 2x 2 2 22 2 ȏ2 Џ222 2 2 2220F 2 (2@ 02`2@2 H2 P2p `2 2p2 x2 2p 222 2 2 2@2А2 ؐ2 222 2' 2 2202i 82 @2 P2`2`2 h2 x2 222i 2 2X 222@F ȑ2 ؑ2 222 2 2 2@2 2i (2 @2i P2/U `2` 2` 2 22 2 В2 2 2 2 2Α 02ܑ `2 p2 2N 2 2 Г2 2i 2` 2 @2 P2 `2O p2 2 2* 23 2A 2i 2M 2` 2/U 02X `2\ p2g 2u 2| 2 2 2 2 2{ 02U @2 P2` 2<2\2l Ж2 2 2 @2 P2 `2 p2` 2u^2 2 29 З2 2Œ 2h 2͒ @2 P2 2l 2 2> 2 И2rk 2 2 2i 02 @2u^`2 p2 2 2 2 Й2- 2i 2: 2` 02< `2G p2H 2M 2L 2`= 2: К2` 2 2\ 2g 2u 02Q `2o p2V 2^ 2f 2Z 2k 2s 2;< 2y 2xE 2;< 02{ `2i p2 2 2 2 2^ 2 2E\ 2 y02H @2 P2` 2E> 2` 2 2` Н2 2 2"K2 2 02œ @2̓ `2[ p23W 2` 2< 2 О2ғ 2Q 2K @2 H2 P2& X20 `2= h2E p2P 2 2 2 2 2FC 2FC 2 2 2 ȟ24 П2K ؟2U 2c 2j 2r 2| 2 2 2 02/B 82/B @2/B H2/B P2 X2 `2 h2 2/B 2 22 Ƞ2 ؠ2 2 2 2{(2 2{( 2 (2k-82 @2k-P2 X2-h2 p2-2K22u,27D 2|,2,2<ȡ2F+С2,ء2v 2 2-<2/B 2,2 2,2d 2D 2H5 (2,02,@20H2u,X2P `27D p2x2|,22,22<22F+Т2آ2,20 2v 2?2 2 2-<02G82/B H2P P2,`2Gh2 x2 2,2H2d 2K2D 2 ȣ2H5 أ2G2,2H2, 2D 02F@2FP2F`2Fp2F2F2K 2F2F2F2F2F2F2F 2F02F@2GP2G`2 Gp20G2DG2LG2J2Jȥ2Lإ2J2LK 22 2J2tE (2L82JH2F X2n h2Jx2J2g2J2J2 Ȧ2Kئ2< 2k2B 2J2J(2J82JH2JX2Jh2Jx2J2J2J2J2Jȧ2Jا2J2J22"5 2 (2F82}H2L X2M h2:x2KK 22 2J2<2߆Ȩ2Jب2J2G 2^2J2J(2K82JH2JX2Jh2Jx2K2)K2 K2K2Kȩ2%Kة20K2 @2JP2GX2 h2Wp2J2Z2J2]2`2~ 2Lȷ2B> з2J2>2q2;2q2< 2{(2H 02@2H2X2$ `2p2x22[202 2p2P2ȸ2Dи22ظ22@22 22 @2pP2p`2ux22222й2222 202 @2ʼnX2Ӊh2Xx22ʊ2J2͊2Jк2Њغ2J2 2J2h2J2i 2ӊ02܊82ӊH2_ P2ߊ`2Dh2B x22< 22g22J2tK Ȼ2ػ222N 2J2 2 2oK (2J82d@2<P2X2tE h2p2J22n 2F2J2!2:ȼ2$м2:2'2:2*2:2 2J(2$n 02߆@2I H2LX29 `2Ep2-x2J2 2J2R202 2Jн2So ؽ2J2<2J2?2J2'K 22 02 82JH2+K P22 `20 h2Bx2y,2J2a 22 2@ 2J2HȾ2= ؾ2K2J2N2J2K 2F 2Q(2J82F@2LK P2TX2Jh28 p2KK 2# 2LK 2> 2J2G2 ȿ2Wп2J2Z2J2]2`2~ 2L(2B> 02J@2>H2qX2;`2qp2< x2{2H 2222$ 22222 2N 02@2P2 `2p2222 2 22222&2& 202*`2<p2<23232J2J2A2A@2\P2\`2Sp2S2b2b2g22x2<2o2o 2:02:@2P2`2p22222222222 2E (2~02H 82p@2&H H2pP25H X2 `2>H h2@2?H2@P2AX2B`2Dh2Ep2Fx2G2H2I2J2K2L2M2N2O2P2R2S2T2U2V2W2X2Y2Z2[2\ 2](2^02_82`@2aH2bP2cX2d`2eh2fp2gx2h2i2j2k2l2m2n2o2p2q2r2s2t2u2v2w2x2y2z2{2| 2}(2~0282@2H2P2X2`2h2p2x2222HH0HtH5j0%k0hhhhhhhhqhah Qh Ah 1h !h hhhhhhhhhhqhahQhAh1h!hhhh h!h"h#h$h%h&h'qh(ah)Qh*Ah+1h,!h-h.h/h0h1h2h3h4h5h6h7qh8ah9Qh:Ah;1h<!h=h>h?h@hAhBhChDhEhFhGqhHahIQhJAhK1hL!hMhNhOhPhQhRhShThUhVhWqhXahYQhZAh[1h\!h]h^h_h`hahbhchdhehfhgqhhahiQhjAhk1hl!hmhnhohphqhrhshthuhvhwqhxahyQhzAh{1h|!h}h~hhhhhhhh%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%}0D%u0D%m0D%e0D%]0D%U0D%M0D%E0D%=0D%50D%-0D%%0D%0D%0D% 0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%}0D%u0D%m0D%e0D%]0D%U0D%M0D%E0D%=0D%50D%-0D%%0D%0D%0D% 0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%}0D%u0D%m0D%e0D%]0D%U0D%M0D%E0D%=0D%50D%-0D%%0D%0D%0D% 0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%0D%}0D%u0D%m0D%e0D%]0D%U0D%M0D%E0D%=0D%50D%-0D%%0D%0D%0D% 0D%0D%0D%0D%0D%0D%0D%0D%0D%0D-.0ĞH;ݔH[=0sLL1aa=0LH=u@ 1`=0YLH=R@ 1`CL 0A9j=1H5K 1 jHT$~L$L-0fl) =0H=!0/W~u=0t?H50 XH=0 H=hL H= 铝H=CK 1H1H5 H=i? 1w=0`H50HPH0HH=> 1-H=0Ht 1 1H=0Ht H= 1ۜ藯Μ=0- 0鶜H驜L%0H=> H Hi LH1H=h> H=9J H1L5X0H=YJ HL1=j03H5-0 H=0Wv {0铖H=?0Y=s0YH3 0H=50Ht 1黛H=[? H=<0H~阛D鎛L50Mu/1ɺLH=0HuHq0H9SH5~ LuuL1LTH=0I륀 0*HT$~D$L50fl)/0H=0,ʔ R0lH=0|,L0)H=0_,L0L50L50L0H=0-,H0{ 0H=y0,L0֒H=\0+Hh0鉒H=?0+L-K05 H="0+L .0ݑL5*0闗 0HH=O0z+ٕ H=90d+n 0ݔH=0B+L0隔H0H0L-a0H=0+>HH=0*L50VH=0*L5h0LH=0LHHEH0L-< HuL-0H: H=: LHH1911H5T< H=0BaH=c: HH1H11H5< H=o0 aH=9: ILH1H=0H59 1d0骎=R0VLH= : 1vZ@IF٢Ax{I@G1L}S1L}阪HE@uIHHEM< u M uIAPIx uIIH}LEѻA u$HDnH^A uMDEI۶HH]I鋷1L}ܴMDEIHE@}IHHE < u*MU1L} uLKLs uI_ILuI_A uIEHIPA u1L}IHULEM< u0M 0I^A{IWtIOILMoAG< MLIIG鈠HC齠A{I_tIU< uMMoAGI鴼IeIHMA trD6A;tqEL~LL11I~IE]A;EuH X0Hq0H5ZE 1=0/aHHAEt A};MAEtA};3MHM@LHh0 IIEA A;EtIH0=0H5pD 1s`At A~;ճM6At A~;kM˭< LGLo< uID$M=00H=w6 0i0=0W050 0H=00L050 0H=0L000L01HLmI釰Lc0D 0H=0IkD l0D]0Hq+H=5 H[0\0DQ0L5R0D-/0D% 0L=-00D0L50D-0D%0L=0< uL< MHHUUA!t!LLH)ZJA? IHLLH)5JAAE/H^ MgDEfBhAMLM@MwowL}MIA \ S}L}MzI=/0;}L 0MHkMDLEuH=z{ 9*HZ0ILM鯼LMLIE1A OA E}LMLxêD0E}H 0AIIkHD9HE[1L}BE/H MgDEfBhAMMM@Mwr钢LMMIA  }LMMzfD 0EV}H0mAIMkNTLU{=0H0HЙ{SH{(H0髙LI0L+:0IH=)0fo H1L 0L- 0L 0MQLL0M)HHLfL9H=0LLL%0IT$H0A$H50L50I9L=0L 0H=v& Lp0MILM!L)MM)I9MG1L5[0L5L0G默H=&0 H=0 L-!0? M0tH=q> 1uQ`;:I)LIT$HsHBD HS0LO0L}驚LL^ іIL9 AE/A};<MTHuIHD>A A }HuM{5=0}H.0IHkLD8LE銣1L}RL}1E7H MG@}fBsEfLMAMAwsfE/H IDEfBkEeLMAIAw 頥At A~;ʡM›LIM0<  MMDEIS=0YzHb0HjxZHx8%H90EH11H=W Aƅ-L-0L%. M]ME9sDLAI|>1ҾL#H5. =H=- H5n. =ЕI雫M H=; 1sN|E1E1H.. H= 0+MH=P0^< t IML]LPHu,=0H5 < 11Rhh0I1HLHHLH 0.HHHVLL%y0Hz0N\!Ld0B+H1LDdHHL9uMM)IpLLHHH{HHH5 B?HHL"HHHHH5 t:HH1y(LHA?@HHH=?, 1LAH0H@|Lc0MIL0M(L@AD 0MhHHAD9\LP3HH1LoL@bLH=+ 1LH5&01H=, 1A111H0H$0HH5: 11fAH=o* 0E1HI, ]Hc=0H3 HHH=0=0HAă=u0 S0HG[ARE1AH* H5-+ H=0hE1AH* H5+ H=0@E1AH* H5) H=m0E1AHt* H5p) H=%0HH1uUHI0=[0H58 1S=G0H508 1SIUPHHHpHcMHscAHu5DA-EH5G. HL * 0L 0L n0A901HHHHHIHH)IIL9HH$1HHHHHIHH)IIL9tHH$LҁLl$IL50IA4$@t @:MHLI)LL9A|$/OD= A/CD=LҁurLl$IL50IA4$@t @:MHLI)LgL9A|$/OD=A/CD=H)HLH)HLIH5 H=*o 11LH:E1E11ҹLL2E1E11ҹLH=+0A<$ILAIH5 H=n 11)LHE11ALLA<$SILAL 0A90O1HHHHHIHH)IIL9tHHH$H=00H0 H=I' \LҁLl$IL5!0IA4$@:t @MHLI)LuL9A|$/OD=A/CD=L e01H5. 1LH5$ IHLHIDH%0 0H0H)HL/H5 H=l 11hLHE11ALLA<$ILIAH=50H1HH53 AQH=0H1H5 & $=0tH=0HH50 1\;uHH[]A\A]A^A_=HHH)HHqHHD$7{IMt LILcMA<$E|$AwD9uXA|$蔃H{IHHHDwAHCDpD Lc`~D$Ll$ED$D$EHIEL$CDH |H=$ UYH=0H1H5$ H1HCHLc끃AHCDC1DAHHD1HCHA D0H H9tAoL<L8HE1DxLcH;vH[Hl$x H=H$ L$ L$ H>0aL%$ L% 0HL$ L$ DH)THl$DtH@DIcfDJ| )#Hl$HSDTEtHHL# Lg0 H=# H=T0H5# HL$ t$ u?01H=,0HtJH|$H5Q# H 0Ut$ HH5`# L$ u0sH5# HdL$ tHS=0H50 1JHͅ H=" V08Hc=a0H * HHH=0H/HO5<0H-000HH1HHHqjHH1HHHqxKH=0711HH=>" 1]A111H9 z0@=00H=! L$ H=! f L$ W00=M030uM H=S! L$  H=>!  L$ H=! L$ mL$ [ H=! L$ OL$ H{@H{ H}01A11H-0P1H1Hx;HDLd$ H L1W1LH= '0EH( H= HD$H{@Hl$EH BH=X +TH CH=@ T01DH׉L$ RL$ =H=O 1JAuLm H=V LT$fH ;H= SH} H= SH=L 1HR H= ^SH: H=s FSH" H=[ .SL L;0&LHAD ?0Mt$ID.AD$El$E|$AD$H=o0<AUATUSH=0tH=0H5 1 UH+ 0H H$~$H$$)$g( $H=0HPH@H@ HPHX(HHGHwHH9tHH-(0AL-0DEEEtwA-u4H5> HAąuVH5. H=! HAlu7 H5 HuAąuH5 H= H wL 0L9 0u LE L0E1MZLx0E< AAH1H]0H9^0uH=00 H5<0HNH 10H-0H= 0H9u L0L-%0L0H-0L0N /ILM!L)LL)H9MGM)L ѹ0L ¹0IwH=0k L%0(- AD$ A$H0H0HH)H~0H4w5H=T0 H=`0H51* 5H-K0HL0H5H)H-60H w H= 0 H=0H5 L 0H0I L)L 0HwH=ĸ0 Lи0fAgnACuL0IL;0L0uH=0Q L%0H1IT$H0A$ H=t0L-u0L+-f0HHHnL9v H=60 H=B0H5;0HH-/0LML $0EL0L0M9u >0L0H0Hq0Hڷ0L0O$IHM!H)LH)H9LGL%0L%0H[]A\A]Hw1H=( 9LL0IYJAAfAAAAMʾ:LLL$LT$LD$LL$HHIM)I :LRuI93L1HMI)LHItHL$ H\$LLH"0D:H<H=0H=b H0H9HFI==0LH5' 1gAHL1HIT1HT$L LLL$LD$LT$LL$HT$ UHH~ ISH5' H~ RH-~ Hc jLe' P1WRH? SVHH=' SUHLӵ0L+ĵ0H1H@HHHYL9vHH=0SH=0HHHH0X[]H=Q0C0HHH5 H60QHGxWu9xnu3xou-x-u'GL@u!Hw@HW(H 1AHv%1'H?uHO@HW(H E1Hq11Z1HD$HD$0H|$P1HHHHL$`D$OHD$HD$HD$H|$P1H5~ 1HD$PDLL$hHt$8LLD$IQH4$LALD$HuI}uHH=0u}bHL$`Ht$PLHQH4$LAHuyAIt$HHcyEl$At)DH3At$MHHex֋|$@uS1ҾH=!0HjH0BHJH\[A tHDcHkEuH5 LHuAW R IH5 L|uEGA A H5 LK`A@ t @ KMgE $A t A IH|$wQ/0xHcH=*0H Hc50Hl$~D$H\$HHH0H|0 D$ 001LH+$=Z0H5$ 1H<A} t!IIAD$\EEE^I?=0LH5x$ H+$1w<H=έ0HT$H5 1JH|$qH 0LI(MA|$ Mt$uIyH9sy t y t HHIA IouIIIL;,$tAu@ t@ tIE^IEuA uJ=0H5# 1;I EIA tA tA<}>ELH=c0LT$HHE1=0LH5" H+$1 ;IEIA tA tAuUELH=0wHt}T$1HgL=-0H+$1HH5! :L=0H+$1HH5! r:Lic CJtGME+EtbECr@uKI=0H=0LH5 1H=0LH5[! H+$1:A t!A tL+$=r0H53! 1L9AEMkE)E}A tA uICztLt(AJ@u!H=0LH5 H+$1}9H9uH-0IMt'E9w t8MH+4$=01HH5 ?9=0LH5}! 1(9I?LkuLL\HtH}LCtmHm=20u3IGT$LH0A%u5IL% L'AG%fH=0LL1H5 FIWH:HT$=0LMH5 g8D nH=,0AƉH4H1'A8H0XH0D 8`AAH̫0EC1DAH41ҋH0A D0H H9tLDLDH_`DhLde011~0p0b0T0F0H30>=C0oHjH5H Hi=0tHH5 17H5 16L815HBH9:ɨ01100000Hl0w=|0OOC<_ V~LFCGHAC}0HHHH%HH)H9tNHH$L1H=> 1DADDDIHq H5&0H|$LMcHDLHUHLLHT`L01E1D9~YE1K<AIDL0L+0IvH0f.g@kH٦0FH=0{ЃHHHHHHH)H9HH$A<DE D$A|$AD$LH=50*A<A UA}AEA|A L$A|$AD$<A D$A|$AD$u2H|$E11E1HJ49~YM Mt LAMcHH)HL H)HL<L9w6H50H=Y0H HJ0FHL}OUHH=0MEeEA I H=ۤ0AG<{ujLH{}uHIE1L)H0DIIHHD9{DLHtCAϋ=01LH5Y F/M)HM}LLIL)HHH9tHH$ujH|$HLH萼HTH=+ H1^%*1LHLLDHHqZL迻H)HL40LI_EwH=c0.Lo0Y0MCLZ0E3vDH= 1L$]L3gLH=0LH 0L͟0 =R0LH5 1-H5Z0Hˢ0L 0HtbH1HL)HHYH9w|HLJH0LH1ҾXVH=| 1L#yL9uH=,0L 80IqH5-0A.LEHH=0L 0H50bHH=ݡ0H5q0LH=¡0H5F0Q _G ^~FyA [A{?AC5A XAxA@A YAyAA ZzuBl YyAA \$A|$AD$ yyADD QyADD IyA AyA V~4F+DD YyAH)HL1ҾH= #11H=3* H=01Ҿ11H=* *L 0L9 0tTH0LHpH5ޟ0%L ן0L+ ȟ0I.L0fA.gA@kH0H={0FH0H90tRLu0LL5SS Q0K0MzL=L0A-<.t A~tXH1H=0LH5R <.t DBNtHH=ў0<%{OHH=,0H1ҾH= 11H=( {H=01ҾhH=0Ht 1ҾP11H=`( @H01H5h 1dH(LH=0LH=0=00L=Λ0H5ߚ01MW92I Ht9*t I9rTI HH|$LH500HDLD*LIcLHJ< HLcH50BH=t0DDm=0=0D/0H=00Aru19g0IH0ILLHMtA9*tL0L9@HHcHL MIL)IIL9tHH$AH|$E111H9yMOMtA9*tLI;wqI LH=0MH9wNH5V0H=0H蟸H0@H)HL(H811)L0CD;HH=0XL)JL<H=l07H5+0Ht0DDIHL!H)HHf0H)H9v H W0Hȃ=50H>0E LH=/0躳IHt'11H=Mo 30M^HLH= 1[]A\A]A^A_GhEHHcMqA9"LkO E:*t4Hxoux-uHxLñt"HL9IzL衱u}tEE1GD-_0HA9HkHI <9Ou1GL=0DD$DL$DT$ D50D$$Dt$Dۑ0L|$(|$0D Ƒ0D5Ǒ0D00L=0\MDD$T$L=0DL$D$$D50DT$ L|$(Dn0d0D Y0DN0D0L=50I9u 0H=`0LI0HT$8H5%0H0IHLI!H)LH)XH9MG1L0L0HHZ0H 6HD$8=;0HH5 1=$0H55 111LHD$8AH=0Ht$8IHcRHt$8sHt$8ELct$0H=]0H+=N0I9wH=B0LL530qHt$H= 0LHt$ʋ=}0H5f 1=i0HH51LQ0MmM0AzI%~lHcIH HLlLI}6IIEH9$tPHl LH}H$H9UtHI9ƹHHNHY &H=S&)HrY &H=;)HZY &H=#(H=x0H5 1]Hv0HH1HHHt| /tXH5A0HtSH1H1HH販H50HtA~NLFH^H5MtMAxKD H1H1HH5HW0H5HD0A u"IEA uA H |$*0|$ L0MHkMlLLUmLD \$fAkDmHLAAwLH=0H5,1QI _ A/tEt&IEA uA/u I  uMA Mn8 [À 0HH=0H50鰪H=e0DH0L-Hu*H ۍ0L1H4) H90H50H1H=M H4.HB|HcE1E1IF\ IcAMA t&A t IEAq9~HL铪IcA\AӐ=]0 =a0H5" 1LH=1EL%0Ld$=+0H51LL$LT$MxUHSHRHuHsHuHT H=rE%XH[] HLHD$LLd$H=֍0LL%ʍ0L;%ˍ0L%0MT$LD$1L0H !HA$=tL0L90tpI@Hq0AH^0L-_0I9tkHk0H5T0H-50IHHI!H)ML-,0I)I9w L-0H50IH=0L0s 0I뉾H=0L%ˌ01LcI<$Ht!9ovH| ݀x[L]A\]GH}R kH=#HH[]A\A]A^A_A t$8ELd$ H\$(L\$0L4$LL$l$0H+0FIH0=0=0H5H1Ht$ HW1H=enLAH5 11"-L0IH5l0H=%1AfL0H5C0H=41H=\0HH5"01H=9AHAAHAH5܂0H=r1AH0H5t1 H8荣HHtXH=ւ0H5V1 rL Â0HHt=H HAA9uMAuE1HjHb`L v0IH5<01AH=MHuH50H=1A량]+0110 0000H΀0=ހ0AeATH#}0H5=1USHHK H5/1HHOK 1HH5'1H HcHuL%ƒ0HH=p Lu(A<,u!HH 3 HL [H5]A\|MHH  [H' ]H51A\V?/LnM1ҾL"I4$Hyt Md$H#H[]A\H=H1*H=+H1H=~0ȟ%L||0A@%HHH90HpHt >*%H=~0H1H1$H-]~ H-z0>%=0HH5D1 H=y0L0+H=\0H-h0HD$E LW0ILL0(LL)H;\$HLLLL$;L5$0Ht$H0I)H0I'\''L0L~H-̀0MpL5ـ0L'LHT$蜛Lŀ0HM)HHD$LT$IM)M9LHL蟝H50H=0LH)H5l0H'\''H U0L{LqLL5C0hH=0EHD$'H-0H~0fE'-L=0MwL8L50MLǚH 0IL)HL$H1HLHLYL;\$**H=0H0'f 'H-0HmH-~0M.ILHH=q0IH)H|$HLL)H;\$HLLLT$IL-20LD$H0I)H0I'\''H5~0MhL=~0HnH-~0I'LL\$誙L~0LL$HI)HL\$1HLHHQH;T$<**HH=n~0LT$L=u~0LT$'H=G~0rHS~0LD$?HH='~0LL$ML-.~0LL$H=~0+H ~0Ht$HL)L9LHLL}0L-}0IM)L}0IvlA'\''L}0LkIhIH-}0LHH}0HH5t}0 HL|L ]}0eLcLD}0{H=}0FH'}0"L-}0L' D}0h'5l0,/L}RALAWDE1E1L5{Y_HH/]ą=01HHHpIIL)HH9HH$ÀpH  Dz0E|AADz0Z.LHM\?MfEM*D G M?E^MfEM*IL?EXHfEL*MD?E^MfEM*EXfE(EXfD.-F z,LfA(fA(¸HH5DeH;H=x0DUUmH=Bx0H{,f(f(¸H5MHEIL]N LJ/ IHHZp@<\AC@Hσ=j0wIN4+H=!HL1MAfEIM M*EXhIJ+螘=00H5HH1LAfEHL L*EXEHȃfEHH L*EXBHK1A@HH;CASHE1E1AWLHE/xHXZHH}(A,Hs EHuLEE1UIHD9L@M;WE1E1LAWLL]wAXHMHHAYH跑HED9e*,뗋=0H51tWE1E1AWHLkwAXAYHHC/LAfEHL L*EX1uHxH56͑u*Lu*HuiH}PLE1AWE1LvZYHH"ID$'H> k H=E}Hw0ADB1DAH4MEE1DHv0AE D8H M9tKTJTIe*DhL%v0&K*A*HH9HH$IAKtIc1ODHHu~MH=o0LEM) GLv0HtLMIA&LHM\MfI*M^!B M8fI*ILXHfH*MD^%A M$fI*Xf(fXf.j'_MAfIM I*XdH=+}*IA7@:fH5Ӣ H1H r0IIUHuƒED]E9ujHο H=r0袓=v0R(t0='Hο 輑H ur0)LAfHL H*XH=[H54r0 jHEH r0a)DFAA@_@At H) pt IH=M}AH5q0tUJހt\\tWA?IHȃfHH H*XH=葔"袐\蓐H5Lq0LAfHL H*XIt$1ɺH=l0cHt H/s0HBH=0H s0HHiDaHE1E}8,HHAI9!"H HL$H=r0(&H\$Hr0HHL%r0"L|$DLILy$=j0H5H=p0H5 1AL' H}HMLL;IHHMSH5Np0 ,$H)HL4rH *p0H=LMؒLMMEH5o0Et.APހt;A\t5A:LUŎLUIE1"詎L' C\LU菎H5o0LU밾,HeHtENC4'H=@q0uD}(H5.q0DHHt }H~McE1JH?/uKuHHC[u#H>?/uSHt1H[1ATUSu=0H51Ot=ː0H517=k0HH1HHHHY~HcH|2H5FGt=u0H51Hk0Hu7LcI|$ sHuI-auxbaseLHx @ BD 1[]A\USQt= 0H51yH>HHH1HHHʃHc…xHp|5/tHH|.HtHs1H1WHH,HZ[]PH=adH1芈H=sNH1tH=i0(1ZAT UHH5zSHHPdH%(HD$H1ILBtH3 %H=pE111HLu=ގ0HH51GtH3 %H=S&E111HL跥u=0HH51tH`3 !%H= HH4HL$HdH3 %(tHP[]A\AWAVAUATUSH=!0H51HIuH3 L%H=dH!u]M dA<>t;A=>tA><u5 =6MAD % !=}0H5611t Lt$KD4H[]A\A]A^A_AWAVAUATUH SHHHdH%(H$81D~H1I11HA1EHT$DH$ՇH\$@H;$HtcALDLLLDžIIcI9LD$uPMLL装HT$H9u2LLL蛅u L)LʁD L证D1H$8dH3 %(t覃HH[]A\A]A^A_SH=H0调HH1ӃHLe0H=萃HH%H.e0H=rHHHe0H=THHHd0H=6HH˃Hd0H=HH譃Hd0H=7HH菃=ȇ0uHd0H=`ӂHHhHqd0H=赂HHJHSd0H=藂HH,H5d0H=yHHHd0H=[HHHc0H=2=HH҂Hc0H=lHH贂Hc0H=HH薂Hc0H=HHxHc0H=ŁHHZHcc0H=t见HHHGa0H=(HH H)a0H=mHHH a0H=OHHH`0H=1HHH`0H= HHH`0H=R~HHH`0H=|~HHlHu`0H=~HHNHW`0H=~HH0H9`0H="}~HHH`0H=<_~HH~H0H=VA~HH1[c~AUATIUHSRHHtH;Lk{HL{HEA$X[]A\A]VtH]* %H=YH52H=d[0HuHH1H=1Y_StH) %H=(HH= [0H蒀HHD[U1SR9Ha0HtH;H[H`0HtH;H[H`05|X[]Y@7WATUSHHH=c0HoHu%=(`0uHu=0HH51HH1HHH}HHHHH|QuIHǀ;tH\HDCDGHuzE1L[]A\ÐAVAUATUS?uHJ) H=HGI1HthL5I\$Htn9kvbA|$AtLL1HHHQHq{ILHsH{Ht zH{1yH{(yC[]A\A]A^UHHSHQH*nH9+ta0X[]SH1H=CH^0HtH;H[H^0AVIAUIATIUDSHdH%(HD$1t/HH5F~HH H{HzI61kINMMVHŁIHHD$ P]_AXIHt*Dd$Eu=Z0H1CxLD HHE1gt$A΅t E1AEHjDHT$dH3%(tyH[]A\A]A^UHAWIAVAUATSHxH= ]0dH%(HE1HH5A e{E11IO,EN MthH5L1{A}-uA}ouAMc0H5LztH5Lzu IAxpLAT$ 1LLcHIIt$IHH)IIL9tHH$At L)JLH\$LIE@HIL$L=DdHJD#N3N< L NL#HIHhzuL֯ N\3 L5M2E1L5A LWH=KDW1AKtKDHHAIIuHHmthHHVADŽtNHLH5'Hx{H5/ LHp{HHHgH="Y0H5k1EtHH= |HHwH vHAHpHJxHuHpvH vL1zADžH53uE1H5 DLuH1HH4HDHHQ]uLID9dH5bD6uDv1ALLhL[HxHMJD#u+H=W0LH5=1LVsHDž1MdMtLsL/sHHuHEdH3%(t2uHe[A\A]A^A_]ÐSHH?rHC[ATH=[0A UUSg2H=T0bHH=k0:W0HS0,[0[0[0[0Z0HZ0HV0HZ0Z0HZ0HZ0yZ0HfZ0HSZ0]I0QH=-[0Q1H=Y01H=Z01H=CY0ީH1H=X0HGR0©HX0HlX09-VX0H=WX0~J'I H;kqH{bq[qH X0H!X0X0HtAH5W0HtFH=W0HtGH5.Q0H-H0H~H5P0H~H5P0H~LuH=?W0HlW0HYW0HFW0H3W0LdP0LUP0LFP0H W0HV0HV0t4HV0H9tH;LcKpHCpL%V0HV0L G0M@Ay%tAA%MYIA(I0IM9uHbV0`V0HtBH=U03V0%V0HV0U0U0HU0U0HU0HU0zoH=KU0WH}U0)^U0)7U0aU0SU0S0S0HS0HU0HT0 oH=zS0HT0mS0T0T0T0nH=&S0H3S0HpT0^T0HKT09T0HR0 T0T0HS0HS0JS0H7S0)S0S0 S0R0R0R0HR0HR0R0HR0m[]H.R0,R0A\AUIH=[ATUSRO1H=HH1赒H5 HItHu=v0HH51IHLHt=v0HH51 Hnu=v0HH5111Lo1=fU0H@X[]A\A]Vt=Jv0H51=aQ0yrH=ֻ11H= 菖HS0Ht'Pt H=Ht11襑H&Q0 HQ0H5P01H=Y1Yy1ZATUSH0dH%(HD$(1t=u0H5H=NHd11H= HeR0HtTPtMH5 L$L pt1ۃ=cP0L!IH=ZH-=1P0mH=ܺ1ٔ11H=y YH Q0HtquH_ &H=X+11H|H[1H=HI1EHË-O0LP0M$1H=b1HD$[qAąyR0y1H=0Q0kUO0X[]A\A]HHtPH  /H= dHtPH 7H= d饧hS _t-t/qw !DAAw O[AUAH ATAdUSHXdH%(H$H1HHl$pHjDdHH# 1L$jDdLH 1j1H1LHH$HdH3%(tiHX[]A\A]AWAVAUATUSHxH$dH%(H$h1%HH5$ HkADžtH5cHk1%1\$AS$AĉƉT$@AAA|$AuthA|$Genu4$@Dt+ <$uA ,$ <$uA L$@T$@EEl$@EDDAAAD%@DT$0D\$XD$$$L$$$AB1AAA݉AAA؁D$Aڃ AD$XAD$HAA$PAD$(D$@A%AD$hAD$pAA$A $DT$xA%AD$AD$AA$x݁ A@$ȁD$Aʃ$AD$AD$AA@$A$ˁ@$ ȁD$A%AD$AD$AA$A@$ˁ$ЁD$A҃AD$D$$$$(D$$$`DŽ$DŽ$DŽ$DŽ$DŽ$DŽ$DŽ$DŽ$DŽ$DŽ$DŽ$(DŽ$DŽ$DŽ$DŽ$DŽ$DŽ$ DŽ$DŽ$DŽ$DŽ$DŽ$DŽ$xDŽ$DŽ$DŽ$D$xDŽ$DŽ$pDŽ$hDŽ$`DŽ$XDŽ$PDŽ$HDŽ$@DŽ$D$(A v0 AÃA$T$PD$DŽ$DŽ$D$PD$H=͉AA̓@A AAȉ$͉$A% D$` D$8AD$AA A@|$HD$$$DT$ T$8$ف\$p$DŽ$E1DŽ$DŽ$D$`DŽ$DŽ$DŽ$8D$8D$ DŽ$DŽ$DŽ$D$pDŽ$D$ptR1ЉǃuCDEDEA AT$hD$$D$bDŽ$DŽ$D$PDŽ$DŽ$D$`DŽ$DŽ$D$(D$htJDŽ$DŽ$DŽ$DŽ$DŽ$DŽ$D$xE$0 |$CentA ف|$CyriA Ɂ|$GeodAttLة|$HHDŽ$DDŽ$LLT$AA|$Ht H$D$DDfHD$uL dLL$@ HDŽ$,DŽ$4HDŽ$8DŽ$@HDŽ$DDŽ$LA1AL$8L$DH$,DЉAAAtENAu[ttIuDMMʼnA AAAEAE] A]{AuH5VHt$<$AA@A!D$AÃ$TA$X$\D\$$PD$D$D$L$|$D$,<$@$01E1ɋ$4E1E1E1D$8D$<FPEwDI[;!XwV w! !A A  A@A,w'$AA@AA9u:AA@AA}Bcw?=v>&AQAA AA3DsEHAA@A A |hwI`w'NAA@AAfrgyw'x}AA@AA_zw{H=|wfw'}'AA@AA =y=AA AA=`u==$AA@AA}AA@AA_A AGA@A /AA@AAAA AAAA@AAAA@AAAA AAAA AA{AA AA]A@A EA@A-A@AA@AAA@AAAA@AAAA AAAA@AAAA@AAjAA AAOAA AA4AA@AAAA@AAIIkEtD$,$0$4EtD$8EtD$<@t$@|$$P$T$X$\D$D$D$D$,E$DtH$D$LH$8$@$8u|$Hv H$8$8$4DHD$|LLD$|$Auth|$Hv=Geod$t<$HD $|$(|$P$|$`$t|$XH &$\$ $-Et1<$u+$t$0Ha HW |$ |$8$0s|$CentuJ<$t <$t;DD$D D$8&|$ AA<$w <$tG<$<$|$0H |$ H# L% IDL &H4 E|$CentAw|$8|$t$0He H5E H AGa3A,-AwBAwH@ AD<AH5 A$A%wAA&H A*A<wSA/w'H A-H A.A7H A:A?>w A=MH A>^VAEGAf AUwFAMw H ALAJ ANH AOAZw AVHS AWA]H A^Avw@AuswH AjpAlfaAl$H* OJA9w#A*H AA$[HQ L .H˥E|$p$$ $(|$x$$$|$(|$h$t$H H 6 HD|$Xt$H4 H HD|$ |$0t|$CentHd Li IE$S$t0|$CentH0 qAH H5 HFV|$H H L-0 H50 HDIE|$8` Ld H=8 L$L=d L }HE |$X|$0t|$ H5 L% ID|$ $d$@|$H H5{ D$@H L%p IDH5[ H HG H4 H! |H sH jH aHL XH; OHO FH  =H 4Hi +H "H: HJ Hh HE L +E H  H H |H sHB jH aH XH OH FHS =H 4Hm +HP"H H E H |$L H5 ID%L `H E H H5 |$8H= t%*|$H H5 H= tH5 H= $L= L MD׃$L= L$u7.$U H H5/ H$H=T H L=} H  |$0HL$u L { LL$|$XL%~ Ln MDH-x $Hr H HEL-l A LD$LDLh $La H n HD$ MEL U $Ll$0LDL%Y ALD H-N LT$8MDHE $xLL$HHEHA AL-, LF LD$XLDL, AH$MDH ) $8L ! L%$ L$LEL $L$MEH- $H H L$HEL- $L$0LEL |$`L H  H$MEL  $L$LEL% $`L H- LT$`MEH |$pL$HEH $XL- L$`L LEHD$pL H  L  L% L$X$@L H- MEӃ$H LEɃ|$hMEă|$(L$@HEH $L$xL-g L LD$hLDLg $HD$(MDH f $8L ` L%e L$LELY $HL$MEH-H $PH@ HL L$8HEA@L5) L$HIEL-+ $L$ L( H$PMEH ! $hH$IEL  $pL% L L$MEH-  $H$hIEL5 $H H L$pIEL- D$@H$LEL $L H$H MELl$@L L% L H- L$|$PL5 H LEɃ$H MEă|$xLE$LL$PHEL- $L$L L Lt$xMEH $H$IEL $L% L L$MEH- $H$IEL5 $H L- L$IEH $H$IEL $L H H$MEL $H$LEL% $L H- L$MEL5 $ L$LEH $(L- L L$LEH $L$ IEL L$(H L H$$L% L IEʃ$H- MEჼ$IEL5~ $H$Hq L-w L$IEփ$Ls H$H k Hn H$HA La IEՃ$L Z IE˃$LELK $MEL%C $L = L$H-: MEL7 $LEL5/ $L. L-8 MEH-= $IEH= $L%A L5P LEL-P $H\ ME$L5< LDP1jAVAUATUASAR$$AQAPM$QRHH=$p$$$0$$($$$$P$P$$X$$$h$x$P$$P$$$$$$($$$$8$H$$$$$$$$x$$x$$$$$$$H$@$8$8$0$(L$(H$  hH IL HLL$PH Ӕ I1jH$H|$(HH5gZYH=|$L=H5HIDH=Eud|$0HPL- IDkEuC$H4Q|$XH4?|$0HL ; ID#L H$ EL HHSH= H5H-!H,$H$hdH3<%(tCHx[]A\A]A^A_HH7I9t@/t/tKHI9uLDA.Av)H;/LKu+L1HH1IfIY.7Y?.tE1FFIEuXL@IHZMZL@~ZH(T UH=蔿H(T BH=|HhS H=ndHpS H=VLHxS {H=>4PH=)0F@)0H(0H)0ZAVIAUL-(0ATL%(0UHS1I9t Hk(LI< Du]H1[]A\A]A^AWAVAUATUSH(H|$HuHS @H= ~H|$E1E1HIHL9%V(0vmIk(H9(0L0LIL)HH1H)9v@LHM9G9w0MtH|$DLDLD$g9vH\$MH\$IMtL9|$rHl$H19w ۸IEH([]A\A]A^A_HcAVHk(H'0AUATUSLh 1Mt3HI1I|AHtLHBuD3[]A\A]A^AUATUSHdH%(HD$1uHQ H=&Ht$HIIuHH=肧{t$Hk(H&0D@ A9~H0DH=0 1TMPA9}9}H0H=9 15.=&0uHP {H=脼A\AHD$dH3%(t?H[]A\A]HuPHP :H= 51HHHHHi H=P L8HYAm`Li|AI uE uE uEuEYALJYAu ALJA u ALJ A u ALJ AYALJqYDH=lHIƉD$Ht$H=VI#YEYALJ< YA u1EA8 A u1EA AuEA XE XMt A:[ Ed AHw Ed DH5S D1ЯELL1H҅^LXH&g H=N L]z=HHD$[=HH|$Ht$`HD$Ht$H|$HHT$HH5TP D1  AAA|$DD$WEE TAҁT$AE1Ll$EID9 ٿDD$1L#t$ t$:#ˁ|$ WADD$L1Ҿ#AGQVHT$H5?O D1CH|$9V|$`HvHT$\Ht$t#t$\t*HIH|$H|$nvD$\HT$H5L D1ЭLDD$ET$Ll$t$1LW"Ll$EI܍?1HT$H5L D1s+|$D$\D$`UL|$Ht$HT$ Dd$Lt$(Ll$0LL$8E"EjA^LLl$\,H:I)HMWtAH5-E1ILt$@HADH3HHT$@LHP=EA2UMcAMWHAGZU|$DD$ ULT$L1HHHP3Ht$WHxHD$j8t$H|$<LL$DD$=tzHcL-Lk`MAJ<A1҃@t AR4HT$AU1EUEAWAVDL$$|H .ETAAGU@THL$LD1H5J 膫H|$6THL$LD1H5-M ^DD$t$1L LELl$AGQSEASEE1DL|$@L1EEI9 \$L HDL|$@E;|$I؉HbL 11aM"L|$Hl$H\$ Dd$Lt$(Ll$0L\$8D$\D$tADD$t$`L|$1AGQSAzIZt Ll$`@Dd$HT$8H5I 1L|$Hl$HT$DH\$ HVI Lt$(Ll$0L\$qH1HHэiEtAE`xRI}DDD$it$L謲VRAADL׺"A-REHHDI RERAwEt(ALJXQH` H=(H }ALJXQAHF-EIF\LsAALJIDHLDD$ u DD$E H IO:QH5LK D1舨$QAGQQAGRLHt$HT$; ,H36H5HHL4uDKA,$EH5 H4u[,HH]xH=j/LH4HHg8L$LHDL|$@Etu#E uMW^A ut$@LHH5 8u?DD$@E EHl$H\$OHl$H\$OH=I 160|$I؉HkH 11誹DHl$H\$AGROLEL1H|VkOAADL׺A?OHI1LH1ILH1ILH1ILH1ILNEDA%EDDENAADL׺AfNE]N1{NH57LLT$C5L\$ALJ%N1EL@LLҿTMLELL1oTMEM1MEE AGUMLoAALJ I DHLDD$ u T$A HaMA SMALJHCMMLLDH51H 1舤$MALJMIcAIOAGYLEAEwLEAElLE8 LLo,HHD$2HtlH|$HD$lHt$HH~H'0rlHH'0H='0HxL'0MxL9}H=G 1虘H|$$/NLH|$%lH'0HHy'0E4 ELALJ4 LEAEyLEPAwEtDH5IF D1=KEKE KAEz1EQAUE1VAWAVDL$$UsH KEKALJH rK1E@AH AL UK6H*Z x H=A IL$KʃAH7LX IcL>H-JDžNDžNESNDžDžN11Ht$4uNHL$hHt$HL$` 3uEAExoNDž`NHD 1D1IHN=v60H5C 1=b60H5C 1Ο1EL@LLҿPIEAIDLfIIL+ILELLҾ11PIAƅIH5LL\${0LD$uALJaIH5-@ LLD$N0LT$uALJ4ILHD 1D1IA8tt9u4A(OHH5D H(D1[]:HH5D HL$H4-Hc1HDLD$H5 D1{H5q> D1eA$ ueDž  t A$ uaDž Q8Q1H=9C QDžQ tDž<_Q1H5B DŘ놃t OA$ uODž Dž O8/QH=B 1耪QH5~> D1輨H5? D1覨1H5 @ D1tH5c@ D1AAA+P1H5@ DPDžl Ox OODž M1H5@ D裗OH5@ D1臗OA$ u/Dž Dž _NH5i> D1MH5= D1虧HN H=6 lA$t umDžA$t ubDžA$< t < uWDž< A$t 8DžH5A D1苖H5A D1xH5A D1eLD1VNHM LH=35 舠H5dB D1(H5B D1H5B D1H5:C D1H5|C D1ЕH5C D1躕H5D D1褕H5bD D1莕H5D D1xH5NA D1bH5D D1LN t&t u u H=-_HcƹHǃ9}HWHπ.uH? u  u u D uD 0 u0  u uuuttutth uh u u u u u u LJ p up AWA1HAVIAUL-Ժ ATIUSAPHэiEGCA)E9sE1D9vS1AG EtEA9w9uH50 2!Ixhu5@ IGhI`u5U IG` E1E1HD$H-|-ʉT$,\$9 |$}@H$Au@MM HH1HN. HILIL)J<A]DL5n/LHD$8Lk0MAV(L$(I~Ht$8WH|$8uH=- HD$8H$H1HH- HIHL$8IL)J< XHH1AH5 HH| 4LD\tH=p-  H=l- rHH7 DE\AtFMXLt$@1HG- LLL11>HLI1HHEl5L$DLH}HuUDIW`:t AAAAHD$H`EuaDd$1L-/Au!H== H1MHH tDAsIlH== HHH1EuH=1> \H1H5/ E1.D9%w MG`EC<(Ik0L D/LH;HH=, E1H1ELSIK4HtuHH1HHQHT$v7l;l$wH=+ 17H=+ 1L\$L\$HsH=S+ 1J4l$AwH=aMG`C(AH$dH3%(tH[]A\A]A^A_AWAVAUATIUSH(  t$ DD$pt$=vH{B 2H=* WA$Au7P=DA$D |$11#|$ AL=`|$LD$AE!AtWwAthAt5EuhAtA t5AuHyH=F< !kH=h< ]H=< OH=< AH=< 3H9l$v,|$tH=<  H=,= L/ML׉HDLL$HDD$DLT$8艺LT$8DD$DD9LL$Hs Hl$0AII MMDMEDt$@MtL;|$0wLD$0IA9rTtPH AtH L AtH rZMt4PEH59 1AQHT$0M|$(5ZY-Au9H E HT$ |$MEH59 1H|$t"Ld$IfE1AuH NL HXD[]A\A]A^A_AWH59S AVAUL-9 ATU1SQIMtgL5h-1MI>Ht.LI uHAD =~uLL1芒H5R 1LIZ[]A\A]A^A_1u"t^tu AVAUIATUSH/HHu&OHHH[HMHIHNJtZ,u1LwH1H&HuLFHNLdMLG<\uK,u HLHÉA<$t$1ҾHԬLMEQEZEYOd[Im]A\A]A^HI bH=F GHI aH=F /HkI `H=F Ik`HOm-|@pAH=I xH=aF 1Ʌ$GA=A]GHI H=$F 謋 /`>AD$@@HH \H=E |Lk`H l-II~ uMv(Mu-DŽ$<HH PH=E 1HmH QH=E E@ @|$|A@H=H mH=aE H%H lH=IE ъH H kH=1E 蹊Ik`H 1l-,@;l$L@HG H=D <7=CBHl$`HLEPAI?ELD$0D$HHQHT$(L LD$0LL$`D$BIHBHT$(L LD$0BHt$(BAH;?D[LePIkPHL ELIkPHt$8CHF H=C uT$E1ɃI,JDEAHJD(ID9L$wAE9LS@;HkF H=C Au'MHC@LAE1A;H&F H=JC ҈EDT$ERAAAHE H=C 螈HE H=B 膈AE19LH1H=/IL+ y/HHLRLT$ L9RHZ/LK/HL9gLX/H )/ILII)L!HH)L9HG1H/H/H9|$ .A>H ޣ 4A4:HH|$H,DD$0L DD$0HJ9H|$ H Ht$WHQDD$0H=9Lk`H=h-t$BD h /LH=U/ >L i/鿩1@ /uAHH='/HT$=L6/HT$6A?0u+w@Xu&LGMEEtBDQt4I6B.BM9t1k BBBH1Åt LèBBEAzB9CH6@ H== BHAU;CHSHDH5L]1[]A\A]A^A_xH4$L1D1L\$KL$L\$BL16DfDH5u/Ik0HtDL$HH1H $^xH $DL$Ik0AE1HD$@D $HT$LD$EH=/INdI<$<$H|$@H|$Ht!DDwAE9E1E11HL$IH|$@AHD$HH4D_HD$(D\$$DL$At$DD$$HL$(HD$@D@ `E[EE1M9HLL$O\N\INXDF\1HH5= w$BH1H5< v BHvHt)1vA1H5O< vA1H5 vAH5< 1H $vDL$H $1HT$@HHt$8/HL$8HUIHtH5< 1赆H5< 1裆H|$8H|$@Ht x1AGAD$ ADpH|$@DwM$$AFGNdHD$@AvA1E1Et%L3AD _BAD$Bf2A`AMAE1H*= H=.: H= H=: H< H=9 LIPAAtL9AAÃHc6L9AA1DD1D1DEIk`MLVHt ELD$D$LMtMk`MAAAƒA Ik`LB>@tcDL$HA1ɉ@?EH=D`-BuuMY EMLD\$L\$4EHU; H=8 ~HD$PLAWjt$0SUDL$DDD$|HL$8Ht$XH|$PAH0EMk`MA~HuEfDHt$8HT$LL/Ik0Dd$DIHt$IxLD$0:HD$8Lt$0T$LHt$PDHD$PI~8<t HL$PHL$H|$P3Hg: H= 8 }H|$Ht$0LL$8;Ht$0LT$8D$L-DL$IAHL$= DDL$HL$HƉIA =CHk`H=[^-HǃHtPH: H=n7 |DGDL/Mk0K| 8HHFH~H~H~ HF(HF0HF8HF@HFHATE1I1UHHSHL 1MtE9AvK|HIHHHE1I$II1HMHt3D9Qv-DAHtLHLHIHICD MHH[]A\ACPwE15HjDPmt$Pjt$XAQA1APEj?H0@DH `7H=49 {E1Htt  DPEE1t$PoHHjt$XAVAU?H0CPCQ1t$Pjt$XAQEAPE>H0CPkt$Pjt$XAQA1APE>H0bAWAVAUATUDSHHDd$PDl$XH<$Lt$`L|$hDD$ 7Q,_@u%P1ɺAWjAVAUATDD$H0du+PA1ɺAWHjAVAUATDD$E1tE1=/AAS1ɺHAWjAVAUATDL$E1tE1=/AAS1ɺHAWjAVAUATDL$E1tE1=/AAR1ɺHAWjAVAUATDL$AMI D)DA)ELMkII:tDE^MI MDBD)DA)BHI9wD)LkII:uAAIIzIM9P{,HuH[]A\A]A^A_iH[]A\A]A^A_RAUAATIUSHAPuHGHkWHH9wDC(L C ALHLϋWO 7H;IH )Љ)AIkHLMIu7IGLDEMI D)DLSHA)k$u+M;$tt1AIkHLMt+IuHHDBHL9rD)M9 $us$3s$Eu1'HtHKHHEtHCHkHZ[]A\A]AWAAVIAUIATIUDHSHHH0dH%(HD$1IH4$LH8tXHPHI9vH| H= x8L)HEt)H[01DLH,$H"H8t HHCHD$dH3%(trH[]A\A]A^A_ÐAWAVAUATUSHHLH/HGH+GMDg(H<INl5L9w H HBI9vaH5 AHD<{-tLH=/HH{,uLxL111HOHt1H H= P7I9tIHIJ{-t1LHHD$H= /+HD$LKL)KIHL{HCDc(L% I>H*s(L AÉAHL~N D>III D)DAA)ELIMI:tFvD@AH{LI D)DAA)BHH9w)AIMI:uAAIM9F{,HuH[]A\A]A^A_;H[]A\A]A^A_SNAUAATIUSHAPuHGHkWHH9wDC(H C AEIIApAPAH EHHH;H A)H AA)AEAAD))AHHH(HHtM$IH9Mt1K$L[H9MPL9UuEXD9]uHHLMtEIuHHDBHL9rD)M$I*I9(uIjI9huERE9Pu͉K$3K$Eu1'HtHKHHEtHCHHZ[]A\A]ÐAWAVAUATIUSHLoHHWH+WMko(H<J;HD$L9w H HBI9v3^H= ƉHD,7LL)A|$-It1LH=/LMD$M)D$AIM4$IH Ml$LAl$(ID$IHHDPH ׉֋(ALI D)DA)EMkLMI8t?DPDZIH )A)BHI9wD)LkMI8uAAIoIhIL9|$VA|$,HuH[]A\A]A^A_H[]A\A]A^A_1KAUAATIUSHAPuHGHkWHH9w*DC(L i C ALHLϋWO 7H;IH )Љ)AIkHLMIu7IGLDEMI D)DLSHA)k$u+M;$tt1AIkHLMt+IuHHDBHL9rD)M9 $us$3s$Eu1'HtHKHHEtHCHkHZ[]A\A]AWAVAUATUSHHLH/HGH+GMDg(H<INl5L9w H HBI9vI[H5 AHD<LH%{-t1LHHD$H=/HD$H{H){IHL{HCDc(L% I>Hs(L;AA‰HL~N DIII E)AEAED)ALIMI:tFvD@AH{LI D)DAA)BHH9w)AIMI:uAAIM9D{,HuH[]A\A]A^A_)H[]A\A]A^A_AHAUAATIUSHAPuHGHkWHH9w$DC(H y C AEIIApAPAH EHHH;H A)H AA)AEAAD))AHHH(HHtM$IH9Mt1K$L[H9MPL9UuEXD9]uHHLMtEIuHHDBHL9rD)M$I*I9(uIjI9huERE9Pu͉K$3K$Eu1'HtHKHHEtHCHHZ[]A\A]ÐAUATUHHSHH](Ht$IH$6LH߉H8tH<$Iž I]HCR0WH<$Lm(( 5 H@ HLLH8uH$HHXHT$Ld$H}0LHH8u4HT$H}0LHH8uHL$HHXH@HH[]A\A]ÐAUATUHHSHH](Ht$IH$LH߉hH8tH<$Iž I]HCN WH<$Lm(( ) HH5LLH8uH$HHXHT$Ld$H}0LHH8u4HT$H}0LHWH8uHL$HHXH@HH[]A\A]ÐAVEAUAATAUHSH HL$~$D$@)$( $HHDpHDhD`H[]A\A]A^H `H=) +ÐSHHHHHT$Ht$HHHt.HPH$~$ H  fHH;JvHJHH[HG H= c+H/ H= K+H H=ہ 3+H|$t(HT$H9wHT$1;l$vH([]A\A]A^A_ÅHED$Ll$Lt$&I}VBY;YHHI1HHLHL1HLHHDUH1HG@Ho(1'HW(H@Et< H0H H HS(H{@'HW8HG0Et'HW8HG0&H0H0HS(H{@&HW8HG0&ALW@LG(I/M Et9M LW@LG(&Hw@L_(H.H Et]I Hw@L_(n&I/LW@LG(\&HC@H(H-H EtH HC@H{(3&H-HC@H{(!&I.Hw@L_(&I,HW@LG(%HG8HO0Et>HG8HO0%AHo@LW(I+L E`M Ho@LW(%HG8HO0%AL_@HG(I(M Et4L L_@HG(u%HW8HO0EHW8HO0Q%H(L_@HG(?%Hw(LC@H*I Et=H LC@Hs(%HW@LO(H)H EI HW@LO($H*LC@Hs($Ho(Hw@EtDAI'L L Ho(Hw@$oG(oO8f f  G(O8$H'H'Ho(Hw@o$HW8HO0_$I+Ho@LW(M$I)HW@LO(;$HO8HG0Et>HO8HG0$ALK@H(I%M E L LK@H{(#HO8HG0#HW(HG@EtKI@L L HW(HG@#L_(Ho@E H@I H L_(Ho@#HW(HG@r#LC8H0IEt=HLC8H{0P#LW@LO(IEILW@LO($#HLC8H{0#LO(LW@EtKAII>LO(LW@"Et.oW(o_8f f W(_8q"H 1H=| %11H} -AIADAD)"11HJ} -A D剫!D1H5| !Ho(Hw@EtKH@H H Ho(Hw@!H(HC@E H@H H H{(HC@!HHHo(Hw@h!LW(L_@EtJ'H2I I LW(L_@?!HW(HG@E AI2L L HW(HG@!I_Hg0H~p@M!I HO8LW(L_@ Hw(HG@EtJH$H H Hs(HC@ ALW@LG(I#M E M LW@LG( IH L!H Hw(HG@b L_8LW0IEtQIL_8I@LW0L g(L g@. Ho(Hw@E H@H H Ho(Hw@ IL_8LW0HW@Hw(HEt?HHW@Hw(HO@HG(HE H HO@HG(HHW@Hw(HW8HG0 Et= HW8HG0hHO@Ho(H9H En H HO@Ho(;HW8HG0+H(LC@EtKI @L M H{(LC@LW(L_@E~ H@I I LW(L_@HI H{(LC@LG(LO@EtKI M M LG(LO@L_(Ho@E` H I H L_(Ho@`II LG(LO@KHw(HW@EtKH@H H Hs(HS@!LG(HG@EC H@I H LG(HG@HHHw(HW@AI&L G(L G@LO(LW@EH2I I LO(LW@Hw(HG@EtH2H H Hs(HC@kHHg0H~p@H!H HO8Hw(HG@:L_8LW0I@Et7I@L_8LW0HW8Ho0H E$H HW8Ho0IL_8LW0HW(HG@EtUH@H H HS(HC@HO8LG0HEIHO8I@LG0L O(L O@HW(HG@lHo@L_(HEt@IHo@L_(DA:DH5w 1)ǃ IHo@L_(HW(Hw@EtKAIM Ho@LW(`HW(Hw@EH@@H H HW(Hw@2IHo@LW( Hw(HW@EtCI L L Hw(HW@HC@H(H@EH@HC@H{(@ʀHw(HW@LG(LO@EtKI@M M LG(LO@LW(L_@EH@I I LW(L_@dIILG(LO@ILO(LW@EtIH&I I LO(LW@ Hw(HG@EpH&H H Hs(HC@IHg0I~p M!M HO8LO(LW@HW@L_(H"H Et=I HW@L_(HO@Hw(H!H EH HO@Hw(lI"HW@L_(ZH(HC@EtQI@L L H{(HC@011Hs $AADADIHc0H~pL!H HK8H{(HC@H(LC@EtKI@@L M H{(LC@LO(LW@EsI @M M LO(LW@sHI@H{(LC@XHW8HG0Et>HW8HG08ALK@H(I8M EOL LK@H{( HW8HG0HW8Hw0HEtXL$HHT$@1H=x/H5q AAjIAtA uAu H;@FAH;@H=x/H5gq 1H[薔Ht H=o H$GAGH+L$HE1MHT$ Ht$@HT$MuXH4$E9eXMcAMMxO|M?H|$AA7WH5o H5NHt$ HAwH<$VDL$LL$,1DD$HT$(H5n HTYIwHNH;gH(s H=n Hs H=rn H;<VFO|@HAs H=Cn HIs H=+n {{xHH!JHUHuHHcE8 JEAKU8Iv mH;>H=v/H5Uo 1HI脒Hu(CJ?9JL#Lu(ME1MLL$ LT$@Hl$HLL$MFXLT$LE9nXMcAIVxN|M?H|$AA7UH5m L7LHt$ LAwH|$TDL$LL$,1DD$HT$(H5l LUWIwLOL9fH)q H=l Hq H=sl HHl$H;:HH;Z=G{"N|1HBKH|$@&TL$HHT$@1H=t/H5m ޗGGG89~UH5m SHPH=t/1@u 褗HUH1SHHPJH߉)HHH;ZH[]7t$ 8Ht$ @A*H P/HAH)M} Hl$AEAD+]ADD!u{yEBME!E!AEHk Hk HDЉH=/ 1 LD$H;1Hj H5l IHL/:HT$LcREy5H;H5 1p:H;7K E1Hj u>/L U/IAMAJAz LT$AA+:AD!AztJE1HMj 1H=/GHt$H;Lؖ/1H&j HNH5Ll 9;/L-M Hn YH=i ' E^E1Hi SV8HHv(H;6H;[ 7H=Fr/H5k 18H6ub1H" 11D$Ht LD$H HH{xt'Hm H=h \ D$H=q/1H5k |$~H=q/H5k 1H=}q/Hf| H5h 1hnUHSHhH$H$L$L$t@)$)$)$)$)$ )$0)$@)$PdH%(H$1H$H\$ H5/H$HT$HHD$D$D$ 0ǑHHHL$A=Hk H=g  @H-;/tOH=j ]H;HH1M7H;e8H}WHJHǃH=j Ht${@EAAHSHF4E1AE1E1UHSHhH$H$L$L$t@)$)$)$)$)$ )$0)$@)$PdH%(H$1H\$ H$H57/H$HT$HHD$D$D$ 0HL$HAHr;H*H$dH3%(t蒌Hh[]ATIH5e USHHxCHHzC[LHH]H=f 1A\ AUAATIUSHhL$L$t@)$)$)$)$)$ )$0)$@)$PdH%(H$1H$H\$ D$ HT$HH5Ғ/H$D$ 0HD$ȎLHL$EH#:H߉ُH$dH3%(t?Hh[]A\A]HHT$0HL$8LD$@LL$Ht7)D$P)L$`)T$p)$)$)$)$)$dH%(HD$1HuHh lH=c gHT$ HH$AHT$H$D$0HD$09HD$dH3%(t[HAUATIUSHHH$L$L$t@)$ )$0)$@)$P)$`)$p)$)$dH%(H$1Hl$`H5/HH$LH$HT$XID$HD$L0HD$P貉HT$HHLAH=uWH;(2LHIH;H.H;Lt#H;.H;/H;L.HHH聍H$dH3%(tHĨ[]A\A]HHT$0HL$8LD$@LL$Ht7)D$P)L$`)T$p)$)$)$)$)$dH%(HD$1HuHf H=a HT$ HH$AHT$H$D$0HD$6HD$dH3%(tHHHL$8LD$@LL$Ht7)D$P)L$`)T$p)$)$)$)$)$dH%(HD$1HuH$e H=` 8HL$ H$A$HL$HD$0HD$6HL$dH3 %(t2HAWHAVAUATUSHL H4$?IIALuHuAU~%H H5` H݈uAUHH߾ @H-f+/L} HIHEHuH1HHHHQHL$u)Ht$DD3A(tEuMtL*^HI9uMt3H$H=Jh/1EMHH5_ SMtL1L5_ E1H_ MuIH[]A\A]A^A_x:LMSHLtH ; IH=g/HH5_ 1[ԇSHwyHDD$L$HT$H?H;H*H;H5=H;[+HH=4_ dH%(HD$1Hu#HT11fD$ t) 1Hc…~fD$ftHL$dH3 %(t„HH9.uy.t Hc y/uHz/uH:.uz.t1D1D82H1AEAHEtH9v x/tHSHHHt$XHT$`HL$hLD$pLL$xt@)$)$)$)$)$)$)$)$dH%(HD$H1HT$PH$D$0HT$@D$40HD$8Ht$0HߋHt$L$迃H=hc/HHD$H$H?-LIc/I8-HD$HdH3%(tLH[SIӉwH=(] HL1ATUSHuH` H=@\ HHuH` H= \ "HL% @DEEA t6A uPH5\ H;A"t(A\u3H5\ H;bH5\ H:QH5~\ H:@AAADt HW@'DDH5Q\ HA1EHMH߾"[]A\@AVIHAUMATALUSHPdH%(HD$H1$H+LLHAHg5uDd$CHC[ÐSHHcWHt,H@Ht#HP1Ht9rvHk 9\ \ H[USAPHt Yډ[H]떉Z[]AVIAUAATLcULS1D97I~LVHtH@HtHH 1HtQ\Iĉ[]A\A]A^ÐQHHcMVHtH@ZATUSHdH%(HD$1HuHB H=A &HHu'GLd$CH;Lp HtCH;X.ECHL$dH3 %(t`H[]A\ATUHSH1]H} Ht89_v&LdMtI<$]L̀y(GH}Hty G[]A\r]m][]A\HtSHjH߾([鶞ÐHO1Ht9QvHk ;D1|D1HHW 1HtBÐATIUHS1ID$ Ht#9XvHHLH1qHYIt$[H]A\VAWAVAUATIUHSH(dH%(HD$1Ht$AHD$H$AAA9|zI|$HTHtHxHt HA;H$I<$D HtWE1D9|$~B48HHD$I?HD$E9~ H&H{D$u H HL$dH3 %(t]H([]A\A]A^A_ÐATIU1SHHC Ht#9hvLHtNH+MH{KHSHt +u [L]A\AWAVAUIATLc UMLESHH(~CH5< L$dH%(HD$1]HHHD$HD$D;|$nI}LRHt HPHuH> >H=> HJHt+yt%HT$I}D L$-HHPAI{CHH{C H5; HH;l$AI}LQHt HxIHuH= QH=U= HH{CoHHHD$dH3%(t[H([]A\A]A^A_AWAAVAAUA)ATIUHSӉʉH(DD$dH%(HD$1AF$x}C H5: D$HHDL$ $DD$H5< H10}CHHHT$HT$D9LcI|$LPHtAHxt:AI|$LPHtIHxtAANHLrDHT$I<$DsL$ HHdыD$+$HT$dH3%(tZH([]A\A]A^A_AWAVAUATIUHSH(dH%(HD$1t`~C H5v9 LHHUL1H5; HUL1H5s; A|$CaLHvH}HHtHXHt$HE1A)AHPANHc3H}T$ 4 HsHT$ t-HxHt$Ht ~DAuDADAE9HHt ~tD9EDLHAO^Hc3H}A迓Ht HXYHD$dH3%(t YH([]A\A]A^A_Ð9w!Ul6SHHcPH荕kHCZ[]ÐHcG;G|PH+: sH=9 gHWÐATUSHH։HSHCHCHCHC Ht=HŋC;C|DdH{IcDcHCHcKH{HH[]A\S[]A\AVAULcATILMUSHMHt HXHuO(eI4$DHH3H]HuH(HI|$HLHNH[]A\A]A^AWAAVIAUAATUDSHH(A~ Hcŀ| tHs1fͿЖHcLIsAmH{ 1IEL{ AoDMEOMl9VvLk F9lFlHHu19~vHk D9|D|HEEWAyHH8 H=7 lEyH+8 H=7 OE9 DcE9E9DAD)L$A)D;c|7GD$H{DT$IcD\$DD$DL$DT$HCD\$DKH{HcSIcH4H H9vH7 H='7 McLcH)OLL$LLD$YH|$LH{HL$DcHH{1Ҿ+l$H[DsMk AVSN\#E+E{Ak1H([]A\A]A^A_AUEATMUSAR3HtAYELH[]A\A]Z1[]A\A]AWAVIAUATUSHHX6dH%(HD$H1HFsH|$ L<$l$Dd$ ,L9|$ ub9l$(Dl$,EuLEtGLLqA>t6HL$HdH3 %(u8DKLCHXD[DH]A\A]A^A_1HL$HdH3 %(t\THX[]A\A]A^A_Ð?t`AULnXATE1UHSHRt(6IcA"ILH1HuAD;eXr HUxHLX[]A\A]U1HSHXdH%(HD$H1HHHHH1tHHאHHHHT$HdH3%(ttSHX[]Ð?tPZHr1ÐAUATE1USHxdH%(HD$h1?thH\$ HA1H}t2HH}H$HsHT$H5SHT$Dl$HD$轍H%H HI"HL$hdH3 %(LtRHx[]A\A]ÐHVHHwH?PHHRH01ZÐAWAVAUIATUSQL'MtA$Al$1%)9w1ۅu1A|$y H1I}E1趕I}AH4HtD藎AIEDxD `tE1I9tKtJtIhZ[]A\A]A^A_ÐAWAVAUIATUSQL'MtA$Al$1%)9w1ۅu1A|$y H1I}E1ܔI}IHk HHtD轍AIEDxD `t-E1Hk I9tOLNLGTFTI hZ[]A\A]A^A_Ã$HHt'1HHHЃADN A)A ALr11H|$H]H4 H=72 L $LEAy0HMExM+EpH1HHLyM9w)I}pLHHRM}p.AH|$LfH}3 H=1 yHe3 H=1 aH|$%H|$H|$?H3 H=F1 H|$HӅH|$LH50/LM]pEM9]xMMpHMAMEpA%6E $H BHmA*I}pI9}xuH|$NIupLs HLVMUp*Ed$Cc|$$uaHT$@ED$<JT`;su1MMpM9MxuH|$IMpLcHAIEps8H1 H=!0 H1 H= 0 Ht$HHߺ RH\$XhD9|$ ;$LD$@H[LD`PHr1 ~H=/ nH|$2IupIH-S LVMUpE\$DE|$BD}tTI}pI9}xuH1 H=F/ H0 H=./ H0 H=/ As H0 zH=. CH0 KH=. Hw0 IH=. sHt$X wQLt$XAA>s0L$I{6H%0 bH=Z. !L4$M~EA/IWHJIOL2HAIGDE1DT$ ADT$$D9|$ 1MD$CH52. 1IQML$LIgD9|$$IEN.L $MqE>A/IM^I{I~I|$AH5- 1HPIT$LHIOA{DA?L41/v IOAHEH. dH= - H. H=, E=UL$I{/HGHpHwI|$H5$ 1HOIT$LH L$MHE1A/MyM_MYI|$IH5j, 1HhOI|$HLH<$Hw/vUHFHPHVI|$HH5, 1HOMT$LIcYEAMyE1fȃHFL $MqE>A/vgM^I{I~I3L H4$HV /HBLPLR0L ) DCAu |$WL[EAM^E>H, NH=+ Eu#AH, H=* H, H=* Ht$HHߺ MH\$X;$u*|$ H[u7D|$, XH=s* :H&, \H=[* "H, EH=C* H|$~H+ eH=* H|$~H+ kH=) H|$v~uH+ gH=) H4$HVDA/vZLBMHLJI|$IH5) 1HLMt$LIH|$}I]pnEALBD뢾H{X}HKx1HLHHHH* OH=( L$MBEA/%MpM~MxI|$IH5( 1HKM\$LI3)L<$M_A;/vBICHHIKI|$HH5( 1HKIt$LHICA;H$LREA/vBMJMqMrI|$IH5?( 1H4KM|$LIvEAMJE뺉ȃHG ȃHB YEAMpEfDŽ$VL@$VH$VL$MBA/vBI@LHMHI|$HH5!1HsJMt$LIȃI@AL$MHA /vBIALpMqI|$HH5&' 1HJM|$LI_UȃIAA H4$LVA /IBL@MBI|$HH51HIML$LIH $LAEA/vBMpM~MxI|$IH5y& 1H\II|$HLEAMpEH|$LzH5w%/H|$H}zc^L, LȃIBA L$IS2/vBHBLPLRIL$HH5% 1HHMD$LIHB2EAM^E>DžIE9tTLLyI}HLMeEK; E1DA.{ E1DA{ E1DA{ E1DA{ E1DA{ ADA{ ADAx{ t|ADA]{ tfADA BDAAAAKA$; uAHI9uE1E1YLHL[]A\A]A^A_E1#E1:Il$4} HH9uH[1LE1HLHT$wHT$mE1~LLwBE1E9 HAHv$ H=" 蒽HL[]A\A]A^vHJ$ H=" fH,w*Hw,HHzvHKǁmH9r4LL1LD$HiELLL+HLD$HSLLD$ LD$봋wA+~?ILSL9S tMZL[E"Hm4H_vLS4ALy Ax@LME1@ǀ-ML$IwUM9rPAAD)AEAD!B<6AAAu#?I M9w݃v =wPIvJJ<L%k! M /IHA7DVA^@uHIM9uE=wIw=wIw=AI@A u(t hLI9?=E/lH=E/HH5, nDHHHT$@HD$8LT$(HT$JHD$Ld$0LT$L[HL|$(L\$@Ll$8/E1111HIHD$0t*:{w2{uH wH=5 Et L\;;LH;n[H]A\A]A^SHG@G HC[H=HWG+ATUHSDg 1D9} H[]A\AWAVL5X AUIATIUHSQD(M9LAVu tHI9uE~"HMHދEL)+HH9|HHLH,L9t9;A~t HHI9uI|; uHH`X[]A\A]A^A_ATU1SHw =Dc A9~ HCA[]A\SHGHHH5 H1=HSH[HH6H66o?/H? H < H/H /UH1HAUI1ATSHdH%(HE17HHPIH HHHH)H9tHH$%t H)HLH\$LHH6HL6H}dH3<%(Hts7He[A\A]]S=HxH0HH° HH[Hk(Hk0H{0HS( H)H{8IHueHuH{L{(CHL{5u;MLS8HK@LK0MZL[8I9E1fK0LpCHtLK0Lk HS(ML)L7IHHYuH{Ls(CHLs 5uuMHt" @H=< Hl" H=$ вHT" H=  踲HS(HS0H9k822HhCHvE1H#" H= oE1S1GD9$L3LH+CHH<D{(H4$LHt$I9L AHE,8LHLD${-LD$LSL)SDMHHLkLD{(HCAIL9L$w{,L$L-2L$HQ H= mE)EUH. H= JA H IBI9* H$1HH=:/LD$HD$xLD$HD$D~AӉ׋N DMI D)DAAA)DIIA?uAoAD~AMMDZI D)DAA)BHI9wD)HL<A?uL$S11HHdH%(HD$1HT$dH3%(ta3HH[AT1AUHH5 SH{5HDH5 1e5H޿ []A\t4AWI1AVH5  Aι AUEATEUSHAR5H޿|24D9}(AO1Ҿ DAHލz04XH޿ []A\A]A^A_3SHuH 2H=| (HHtOHxH@Ht1HCPWHCC(HC8Ht@HC@CH[ÐWGHGG G0HG@GHHGPSH)HuH\1HtPH[H=8/11鸎ATUSHpdH%(HD$h1HHH=8/2HT$H1H\$@Hl$8Hl$H5 L$H\$HH=S/HHT$ f3Ht$ Ht"HD$(H=0/HHH5 H1:3H /7H= 6HT$ H'~HH kH=/H5 12HT$ H'~HH kH=/H5 12H$ H'~HKH kH=R/H5 1d2HT$ H'~HH kH=/H5 1&2HT$0 H'~HHMH=/H5 11HT$@ H'~HgH kH=/H5 11HT$H H'~HH kH=Z/H5 1l1 I'~II kH=!/LH5 101HT$P H'~HH kH=/H5 10 H'~H>H kH=/HH5 10 H'~HH kH=k/HH5 1z0HT$X H'~HHMH=*/H5{ 1<0HT$`H=/1H5 "0L5/H=/1H5 AP|0L 4/H=/1H5 A/H5/ .HD$hdH3%(u-H kVHMHMHMvIM'HMHMH kHHMHMHMeHMHp[]A\ATUSHuH  H= \HHuH H= tHFDDEHhH+[]A\AW1ҹH5 AVIE1AUATUSHhdH%(HD$X1HD$0HT$,HD$HT$H2/s A9:H A9u Dc8Dd$ AGHH4t$ IcDH5a LH1HC-L$ LH5 1,-HSL1H5; -SL1H53 -SL1H56 ,{S1H5= )L,SL1H56 ,+;l$ PH=1/9(uHY [H=Y H51/H|$H蒊|$<Ld$0Dl$8HT$DL]HRDAH5 PDL$HT$ DH1DL$0McIJ|E)AGTD;T$LIcDL$H=+/[Ht$hDDH=i+/,H]+/H$,ZH|$`1ҾH\$`L$L$DKEQIN\ DSM3M{L%j pL% gL%F ^L%u UL% LL%M CL%a :L%s 1HT$`HtHHt$XHtHDL$8LD$pLVIH|$`Hty G!E1H|$XHt-D9ovEAIJ| ڀGMuZT$x9T$}79}<9$ }eI}IHHHtD^AIEDxD `t#1HH9tAD4D0HhZ[]A\A]A^A_AWAVAUIATUSQL'MtA$Al$1%)9w1ۅu1A|$y H1I}E1`dI}IHHHtDA]AIEDxD `t#1HH9tAD4D0HhZ[]A\A]A^A_SHWHHBH9vH{,H;u{-tHSH[H=%/Hc[HUSHRH;Ht H/H+X[]ÐA{A{IICL3A H|$0-\LD$@HD$06H<$HC<$H|$8HL$0LLHD$0H$HD$@AԄt/LHCPI9L#LL$0IL LH ~H OHLI$AGIGHQ8tH LʄMHH L11~L-M/UH-}OSHQH9u H?"H9 u H(*"H98u H@"H9Pu HX"H9huHpZ[]!X[]H H HEH= H HEH HH Ho,$Ht$Hi HH8ǃHgH|$H 1LT$p}D#t$hLT$pH|$H> 1|H EI Hr L1|1HH$D$D$H MH= wH @H= _EuA`w EEEEEI EM YH|$HG 1L\$xL\$p|LT$pL\$xHC H= Ld$A$HcLԵ ACH|$Ѿ1H {AE=`w AuAu@YH EI JIMt$A]`wAUA]`wA]LD HA(tSMtEEA`wEEEEAm`w AUAUIH|$@I L HHNMMtAM`wAMAMA<ILXA"tLd$ALXA`wAEMI'tLd$LXA'MLd$LXAu`w AUAUL$H56 1L H|$L1H vt$`@LT$`EI M t$`@LT$`DI I H lH= /Lt$Ld$ o H0HwoP'H`HxHH9HT$HHHqRH{HT$HKIH;HD$HsRLT$HIHqRHkHHiHL)L|$(A4'AE1AWH  11H:uAEA+quhMHAAAAQ11H HHL$LT$LL$tLD$L|$HL$IwH뛾H1L\$H OuHL\$lA1D ilL$HHAw#H!:H 1H1>t uDT$$ADsH 1u6LCH;HD$0IHsPHHCH+D$0HD$ mt$ODL$D18JL$E1Ɉj|$@zDD$ AWIAVMAUATUHSH(L&`HT$Ll$hL$MD$LL$u?uLD$Ha ~LD$H 1H1sLD$6rAL$t'|$u H1LD$H sLD$AT$ut/Ut%H1LD$H rLD$LL$`1H= H5Χ A $IDOtYIMt8MuH 4H= WAU`w EUAEUAQIcDDtL;d$rt|$tH\$1>M'tLH L)Kw"`AŃ$AtF߃߃@t<xD(Aw&LH L)H1qi>|$^>$uFztI|t#}uƅ|H0 H1GqA$AF>=A<1H5 AA9tA ALcB;\wAH߀A t0Au!Au`EA AHcD 459 V5 ^5W 9(5 5wT 5w S5 X59W 5 5> l9b505w).555 5958'90 9A8Q9n?9on'9U9w3I9wA9E/98N98a8wW8Y88e8i888w?y8wu8w88t88c8W8wI8m888,8P888Mw8L78777w 777777x7wHj7w\77K7?7c7.7"7w78776!776QP6! 6 wK686w656n66Z6~6B6c6.69w886(>6)60#65@6A5H555wE5aw`5Y5q5h5]55E5f515%5w9w 5054544w44444444x4?ci4PwBKU4EL4wAA4Ch434G*4IQ44W4w R84S3U&43Y4Z3a43u3w?pw)k3g3i3e33r33{3w wp33y3Y3M3w3h3333wZ3w2322222w)2222|22k2wHW2Mw LC2d2/2hP222w.2111219i81:11wT1w~11m1a1U1y1D181w&*1T1E1113010wH0 w 00000)w (0 0o000[0C0aw]`/0Iw H0@<00P+0Q/Y0/w /h/////w<w //l//X/L/w)>/2/V/!// /-/.e.S.wBE.wA.C..G.J.O..Zw Y.U.W.w.an.c.`.zwEyR.oI.wgk.6.u-.w$.sK..w .#.-.-vu-Vw)&w5H&&C&G+&%w)%M%V%%%%y%w}Y%w9I%wA%E%y%Op%U%b%iY%waN%eu%@%o7%u^%)%%wH%w%%%$$%$w $$$$$A8$HPHw$$oi$wO^$U$P$#D$C8$u_$*$a!$whLw6K$EwC$A*$#G$#UwR#N##Z##uw9r#lwg#c##n#y#m#wzb##Q#E#i#4#a+#wBI #wA#E<##R"U"O#"r"w i"o"e""u""t""A4"HAAHy""h"V"w<H"wj"5")"M"" "w."!!"!!w<!w!!!!!!wx!!g![!!J!>!,!w<!w@! ! #!  w     wH w~  m a  P D w6 Z %  =  qhwQowOUuw oL[1wH*Gw 3 T@ {w rL~tKihuOw9KgEwDYA}HHl7ZwY)RMa?bd*wQwwrkyzw t\}H>=0w`w )-w ($09zUwHTfHw GRCs>L_*aw `X7d&eh  ElD'&wHw ~jVw Bc.R7wHw *  'w &".1r>^FgwHd2Yw XL? `+}w xjw`w z fNo:w &G6qwKhw#Uuw  kx{St?wy+w9awA3'w8&~fRewWd>tws0STZC]`(gw d`jkHGrTwHRdHwGVCzEKlL3NZ%lw,kc>eg)nr !wlw&t`:w 9L$m8=\> CA w`]w XT`adw xdLm8+w`*$w 1  qw8X0=Dxd0Xi:i1wKO&w EIA9aeUw#ouwHyw eQr=w )J9(wHqw hLw mY}Ab-wH1w *&&Sw L,r{Q>?=qeewEdQLHwDj5N,VTJuw tln%wZw zw fR9s>&qwHhHw GCd w  kwHjw r ^DJw56xZ{B . w9 h wH $ " # & qht w}` iW w0IL wEq < U3 eZ % w u8  $ w8    ( - 0 w`r w ^  J n 2 S  w8 .. / x    UWT r T w X_ * N  6  Y w<wua1w80M q!5(V!8E9 P*wxw8`ahuiw,Op;/wQ4w<ww~ratUw, w/;`\'w|= 'Jw'H"H#g Hੇ0HL@k _* NG =G ,G    F   Hੁq [F |GF k6 * N : &%=IU&I0B]0Q0wwS00U0TY0[07o0wHd0w_0a0f0h0x0wr0u0{0u0d0X0FwH08w0*0N0 010w00000wH0w00{0o0^0w)0J0>0b-0Q{0w 1HDT$LD$3LD$DT$XENAAENBAǀuLL$wD$IqMMAH- LIȃ?IHˀA>wB\uH- HB DA@H9 rIL9sH) 1I;HT$dH3%(tLH[]IHHHH=AWIAVIAUMATIUHLSH(LH LdH%(HD$1HT$I$D$LD$H $=T$H<$LL$vMTI>Iuw/Hv/E1HA@BT$@ψ4 I$ImnHw MI>[DE1A DAHAAHDHAF;4 DD\+HՈl+I$ImH|$dH3<%(tH([]A\A]A^A_HH 11v0HH 16H8 1A01ĜH:HUHSHAQHHHIIуt2F\ <AAAB< ADߍ(v"wLHuHEH+TZ[]ATIUSLH2H1H1ATH@E)DD$A(=wPHHHHHAD9EL1ŸTAE$AwQ A$HHL‰u2I $HUwHHI $HUHHI $HU[]A\AWE1AVAUI1ATI1UHSH1H8dH%(HD$(1PHHCHLl$L|$HKLd$Ll$ Ld$HLt$H)HT$HL$ MLLLHH|$11MLHHtLCL+D$ LCN8HD$ H{HH;Hs 11MHLHCHH+D$ HD$rHu@8u6HsH;HD$ HHsA HHCH+D$ HD$1H|$(dH3<%(tdH8[]A\A]A^A_IHHHH=)IHHHH== SHH#HHG@fH[ÐH?UHSHRw 9w|H?s HcHk HHcCHHKH,X[]ÐAUIATIUS1Q9},Au`w AEAEHLH H {X[]A\A]AWEMAVIDAUIATIUSHHH(dH%(HD$1HÐH,H- H9$uIH1LMHELHHPAWZYHHm HEHL$dH3 %(tH([]A\A]A^A_UHHAWIHRAVAUIATSH8dH%(HE1HHHHH)H9tHH$%t H)HLLd$Hu1IHuL d L` LeLUL9@<@\tIrHuA:E1LҀ|uLAL)H1H)F4HuEt$L9sDCDYtCHAH˃$uIzH}A$HHUHuHM]HML d LN_ AtH LD0c0H HUI@LL)uHMdH3 %(tHe[A\A]A^A_]ÐUHHSHPHU-1ɺH߉&H߉E["HEZ[]Ð=`wW‰HH H HѾ1H )AyuJMtgLMH L1E1(LH L1E1(HMH L1E1(鞗LH L1(逗xWX[]H H1d(HnLIyHcFVHu1L Hk1ML>H*LEI0H€xI龒H@HHLH0t LMu fAd$Xs0LHAH( H1'/@u!At=H H1o'HHH H1H M'LH5 H1IJ''H}mkx|IcOAWIHHk1ML1)M?H= 鰕LHT$HHHT$@ukH YH߾[1]&HHH=/tLMt s0HHAfe隖H H HHH H AXH߾[1] &HH HH@u\t{H H1%1鎖H` H1%1qH H1%1THHHZ H1H %10HHs HHH1e%1HkIcEAUHL Hk1ML1(Mm7{ qfCfG@LS(CHCEZ<ƃSD[0}DxIA5HPB5H=rl.LkLkBDI~HjLI}Z䀻uEߘCC{ؖA7t'A饘fC\tu {L5j.9b2l%INHb H1U$rGL'l.M9AFE!INHm H $H H1:#INH H1#vbV :rEINH H1#{ULHjL(IMHi.HHAHHD$tkLl$AHs(L H{(A6&HT$LHmLL$HMH L1(L鿕H齖LH H1"锕H H1"Hb H!y޿JHs0HHLL$DD$HRAH H1z!HT$ H1LM LI1.$HiH|$H̑V‘H|$H>骑@E1輺HIŀ{E1HI@<txuDHHA>Hߺ$HD$kutL|$1ҾH蓎)At#HH HH1GEHEƉLH蚈AD$tH H1HD$dH3%(t.H([]A\A]A^A_Ht+HHu0H醒E}mdoEHLI|$0HT$ 1HfoL$HPHfHAoUPI]fHHX(]E鴑mH+x5IvEcđH 11UHSPH%HcHiHHH3HZ[]UHS1QHt}t H}HmZ[]ATUHSHHt7}tH}HHHELcpH8VjHmHLH[]A\SHHH H[&AUIATIUHSHQMtLA}tIuHHHH31LHHHHHQ4H{IEǴMmZH[]A\A]H L1H1XH H1fM1H5efffUSHQH7u+xu,HP209vwuuu3u -1t&HH蜰H( HH11Z[]ATUSHHl)HŊ@w0H)@pI@St@u HA|$t1H[]A\USHH(dH%(HD$1x>t-@HH H HDHW 1OHHpA>Hߺpt<$t@HL$HH1փH|$诲HD$dH3%(t躴H([]41)AVAUIATAUS1HL'IƊ@t#HHb HHH1HHt HPs0HH11[U1SHHdH%(HD$1HL$H$Htv$HHH9_yHH 1H1AAt?1HH H1'H$xtH菼111HbHHD$dH3%(t$H[]UHAWAVAUATISH(dH%(HE1HuHHA>Hߺ$HD$litLl$1H;uLHE1ZHAuHAE1uHE1AAL 11HEaj$1At&H蟧H HH1 Hy}AuRE HHHELcPEyLH 1H1G BMtL[(IMtIzLEuLC(DLDHAH8E{EtHD$dH3%(t|H([]A\A]A^A_HuH] 1 UDSH1AQ zHt@hHXX[]ATIUHSHdH%(HD$1HPA$HHt0P1Ƀ?uH4$HtHЂH8A4$Hxu H1HHL$dH3 %(t艫H[]A\UIHHHHdH%(HE1IHIMZMBLIL)HHH9tHH$t H)HLHT$LHHBD LLϾwHEdH3%(tѪ1~H.UHAWAVAUIATSH8MHdH%(HE1FHHHHHH)H9tHH$%t H)HLHLd$1I:LLL2M@LD:M9v(A8\uEPA"tA\uIEIIE^A 8M)IMIHML}HEjLLILnI]LcHMt IT$PHSPI}(AEAEDG~D$D$듹 5kT$ L 1L1g k kAru3A@kASAL, 1SDҾL1[]gLL\$A@DT$ϱDT$L\$u'As} j vj[kAm|$H|$8|$(jct$@@$AXcAL 1DL11flErEhE1A}g@|$@L1HT$8Hz DT$PD\$HUHT$8|$@D\$HDT$PgH|$XH$0(LL$`L$8!D$P$@LH 1HAu0LAU?iMMiHLAiL1I1(nL!I!nAtMAt|DuTED$AudLLExL# IHD$qAtoDIc̃0dI7LEexL IAuˀ$L== DLL ڿ L MD11H DL< DJ0A}eiMLq 1DҾ L1f$~$8iH|$8D~|$8LDT$`D|$HD\$PDL$@D)$0W$H$H$HH|$8Y`L$o$H$)$PL$XL$`L\$hH DL$@D\$PDT$`kHDHT$HHHH!H9jHD$HjINLH?jHHHHL!jDL$X1i1jD~l$PDT$pD\$hDl$@LD$`@t$HL$D)$AP$$$H|$8L_H$Do$L$D)$L$L$ H\$pL\$`H t$HLD$`D\$hDT$pD$XhHT$8ANHHD$PHHЃhD~L$8LD$8LDT$hD\$`DL$8L$HD)$Ƅ$Q$$$H|$8q^L$Do$L$D)$L$L$LT$XH L$HD\$`DT$hhD~\$8LD$8DT$hD\$`D\$8L$HD)$Ƅ$VL$$$H|$8]L$Do$H$D)$L$H$LL$XH L$HD\$`DT$hH\$HH hANIIIAwhH- jA$EuL5 T$1ɾL1E1bqL觪uHAA0@E]qEP1Lֵ LAWT$ 1݁ZY@(qvr H@UL}@LIӃ AAAbA$pA T$11L L} t'A$tT$L 1L1QAtA$u;A$t0A$`T$LL L- MD11EAHpDI0L" AtL= T$1ɾL1E1pA$spEtAw~@A@'sA$ sL EGADA(wnHy ALc I>AVEL LAWT$ 1ɾ1E1_AXhoILP%; HppAuLE1tHT$HtL:A$ruCA$s AAnA$`_u 1wMtaHI"oL軧uA$s@A$Iw'Mk 0LcMMt$oIHu@ v@xnFoJo@h@lI In}lnӃ@Isn}Lin@H= L T$E$`ELD11LA$t-|m@HnI nӃwmOmA'uA$L A$A"fqLx fIWAkpA$rL <A$t#EuAM +L`EhEuAw HMMHt1H:L~L0L_؃ !LHt1LHHDLDA @AEKD@@EKD@EKM{LD@DKDA @ADKDA@@ADtKHT$EpLHMhAVЀ w}HwtHk AM0HHLMuHT$HLMKA K J J JHKIKHT$AxtMIILM~KHD$sKAAJAJAJAA@rJMMIIA}MHMH?wHHHH!l$@LHIHIՃAA8 HD$HHЃLtuH0 1eL$L$dM A DL$Lt$HQL$$$=PoT$0Ht$@Ll$0$H$H$H T$L1LPHLH$$$No\$0Lt$@Ll$0$H$L$H LA 9KLt$LIIIM!DKHD$tKHD$1dKHD$HHH҃1LHD$1LIIIL!LHMH?wHHHH!\$@u2LHIHIՃAA8qLHT$HH҃1ZLpMH<$~ $1H$ $XMIIMIL!LHNH?LIIMIL!LLBH1L1EuL fLLVMAJIIAE AEIH9v)HUMMM_MHHHH!MLI?MHDHHI!wMLVM‰IL MMLIMLH@MMIIIM!MHNH?MHHHH!MLHMIL$NIL/NAWWAVAUIATUSHHFfGHT$ @xuHA/HHE1EE1<>tiuHtAHu~lt5 Iҁ MtIȾ @E 1[]A\A]A^EtFtGtHtIu<8ø9ø:ø;|$HHT$LD$uVH@v*H@H?wFDNLs<@)HHHH &NIsHH@t@H)HHI HT$~D$LD$LT$LPD$D$D\$hAA@t3LLLL$1 H$AEt4LHUrmM$$ oLLT$@eHT$@HH$HcI~D$@lIH9}mH;D$rmLKH\$ ~ AMm(E]8HhDXH>mLD$3qn$0H 14h\$@BD:/L|$Hl$HHH<$gHHXH1HH5 HII gtH5m HftLD$MM9Ht$LH|5HPgHLL wI\$@Hl$HAH<$L|$eHT$oILHui|$@u&|$,$0T$4HLkHЭ L1Ly5xTuH L1IV@Ht$LIFHtOLmt:ML\$ MMV I;kHt$ L6I(vkI~aHUHU$H}oaHgaLL$ I9t1=kI)I(L1$kI\$@Hl$HE1O|'@HLH[H9jAh$01LLL=nj\gHNj]L)HHH|$HH{F\UHuHIL LL$KeuHL$HD$HtLUA<2/t /HHLHM|$HeALLUNHH} uHO 1Lu IMc(MtiLLAHHeAdžIF0g`AbAdž!fLA>tiHNL$1LHA[HHH|HL$ZH$HHHHrIHFj|/;j/LD.jLE L4$I|rHde_Dbǃkǃ1kjE$AHHKLA$H{ǃ^HCHEu ~GH{xD$HHLL$0H\$PH|$0Dt$ILFHD$L$Ht$(LL$Dl$#L$$Ll$H $I9"IH|$ILHHt$(Ht$a|$HHD$H|$HHpa|$I|HT$zE"HAƄ$E1ƃGE1$GD|$M$Dl$AMtKL9t@tRAuLM9tmMv fƇƆG=FDl$D|$FAtDl$#L$$YFx I}L,$H|$L,$MFxL9CxuI~(MtADLLQGtHSxIF(I;WxI~(BA4IGLLT$PL\$IrxIz(ISD$HUH|$Dl$#L$$ExIv@MHt$L $WLT$I<$H<$IǀLP@3M^IM_Hs(I(H$r_H$Ht#AFIGLFEL$ 1HLD$ D$ #GHLHuI{FD$ ]FLCT$ LH 1عFHSL$ L]LZFHHH;B.G@"GHGAX1H5Ӥ[]A\A]yHGGE1GHGHH H1LGH oGH\HUSHRH(迊H0賊H@觊HH19H8HtHoZHHHtH_ HX[]SHH0YH;YH{YH[YE11EAWAVE1AUATUSAQHG(x<v HHtDsjAHADHY1ɋE A9~)t2u-HHuotMHUEt tHUHuHUDHuHUD1AXH[]A\A]A^A_7X[]A\A]A^A_AWAVIAUATIHUSHHL~HVdAńLLA$Au[ǃA$kt_ID$(H=<.9P0v-Hw(H;w0r.T$ ZT$ HNHO(.ƒLH5 1W![\L{HD[]A\A]A^A_ATAUHSHD1HE1REHHjv\Y^[]A\SHHH@dH%(HD$81HYHu=H<$HHR($H$HHx H`.XH9$1HL$8dH3 %(t9YH@[HxFHIH H WHHL$LHu\LH$V$H[]A\A]A^A_H<$11HވD$LVD$IHsxH{(IKTQGSHHHǃ8Hǃ[=HHxtlUSQHhuSH}8uLfuBu9H>HuH~QHCHHsHH}HNHKHNLEIt$HLMMLtB|/t/IIIOLLULILRL[L;[rH\R u~ISHSA; ukH/TMd$ KHEdH3%(tnTHe[A\A]A^A_]ƇƆUHHSHQ0H(Hމ~HtHxt HPtHHZ[]ATIHUSH0I$(Hމ~HÉ%9t I|$(誷HtH{tHSu9CvHH[]A\HHE1E1HPPHR@jVHSHH H(dH%(HD$1H$H(HH5HD$H<$HHt$H QH 5.H5 H=y JSHH1TH<$H9\$v=HD fEHHH PEHw(UHSHHdH%(HE1Mox%tHXH-ox7tHjXH ox>u HvHpQ</u DQB</tH*XyLMtmIIIILHI)L9tHH$At L)JLL\$HILLHߋ@AAHEdH3%(t[LH]H-HH 9uHHH9u1AWH1AVIAUL-1-ATIUSRH~HHYAuIH9u~ImI~HSH{MufAHL<D@AAD@fDHEA?fAEAAE A} fDXtAA?AE fDXA} xIHF-I9aX[]A\A]A^A_HICHvHHHH@HKHSH)H9rH9rH3H7HHKUHHHuH@@HCHHH{ MDHHCHCH[H{UH*UHHE8HHBHU8Cx MVHHYAeXD]GdDeLe,WM9teA lWMgZWAwA<0H WHH)YAeH LQ.VAWMgA<A}VIIU1M}L9UM;VHHH $XAeH $W4LA V} tUIM|$ULmMH;k tA} vUL}mUMeUHHH $NXAeH $W:Um_H H1聩_IOf\Hs(A HDT$H ږ L Ɩ LDHыV uY_IULH%[`tH H1hfH/ H1MfIIT$A6HL)HAL\H֓ H1[x"UjU`i`U|$tfAN H;H5 HIBM)EWDFED{EGMLD$sA/DHD\$|AFOHT$LE~HxIF/HD$.G{ |$|Hp9x+Mc~LcxE_IIIc=HcxIvLIEHHpH9FLcxILpM!C<HcxEHHHpDWxBYXLC(A HÑ L DT$LDI+AP<1IȉH uifAD$5LLHMD$kDT$4ID$D9`IWLH`HKg`QhCiGhH 1H1BH 11H/KietCitge`ZeHG H1H1HW ϙKi#eILfAL$AD$)_fsaHH3fAL$AD$(x_^Hu( H L LDI+DD$1VL)A}Iu LA WAT VLJ ATH1ɾ1ܗXLZY[]A\A]W2A$'HH9Gi{'=iA$#ihHCIEuGL\$IR ILjLjLL$LT$/ ZYL\$HL$H)4k1{UHL\$@LT$HD$rHt$LB3L\$LT$uHIA$|t1A|$u)L1L\$AƄ$|H! "L\$M$I2gA$g)hg(hkHPks1IIHHl$MX5pHMо1薕I} I}H{(p/t(HS(LeLH+ML H1R<L~lLhMI9D$ tpx oLXo,nH H=} .pn/meIqDCD^FHYoHLHD$AeHD$pDPHxCLrHLLL$@eHT$qHHLMIL9tpA{ rI[rECC<LXrHLHD$L\$@eHD$L 8.*rH\$sH[A1AUrHIHHl$LYanL9MlHk(HA/1UeHD$aoH{(LI+uς1ɾH߉LD 1L+(8.LekH{(LI+u菂1ɾH߉L 1詒L+7.PijHxhI9BEiLS(L} HAR/ItqoqA IEUA uIL/IVnHzH5y ",9nMl$Am@ t @ qI1nA|$ @n 1mHIM)ImH5+y L+mA}UIMtoH)HmA}OUGHmI E}A t A jpIEEMMAASuMMMEUA-wL{IIAATaE]AAHNEeAAR;EuAAUtHAO"E}AAUAEHD$`HD$hJ8HHJ0H $IDL$7M1MD$M)D$0LD$8HD$D$L\$(LT$@L$M9#DL$LLL$ L$M;"=AJ \t1AL-.C< L$_H $AeaH$례{tqLA=Hz 1H1LT$L$uLT$L$ACOnHD$`H3HD$h~8HH~0H<$E1Az8AGl?@Dl$I mHD$`L3HD$hAn8HIn0H,$AMLHH5 3D$AwDl$0HT$oDl$0D9l$r/L9F,IF:*tAD$ L$7L\$(MMτt,A?_ A_EL%X CDDXL M9M)H|$`Hl$HL$Jt=1YH4$Dt$HH|$`DDvFHNH|$hHHwHWHH)#HT$hHH:HJH+JH|$hʃ|$c@(LLLl$@LL$(I+HLl$L7t |$AL $@ DLmt H13L|$L$HD$8LLLA=HMtHM26lLd$`MiLH:HEHl$AD$D,p"!E1D$D$0 {{tH+HM H9MM)LHL$`HLD$hLM~H;Lt$L L9?Gh1L'HaHWL#E\$8M<$IM\$0ML$shH ^H=cm H|$(T$711Ln MMT$H<$HL$L$D$=FH{(1ҋG w<HHHH+0D@BtpH;LS(Ll$(Lt$`EJhIM9*HMGLLOAoAAMQMPLHpL)HkH~MeI{M9MOIkjHgHWH+WHi«A@L @-HMgiiHPHߋJH2H@DPLiHNH9j 1zliHHU H\N9OAC1a191AL%-HM,FkLH LH\IL$HAH9jjAHH kSt 1QøAIL -HcI  A5tDZ1H57 A9LREfBFuA$]zPHȃ#1Ã.AÃ%A A7AE A1*A?A>AE 1|1&ÿHHHtHHOHHHwHOtv.t11øøøø1@ƍøøø ø DAωHDEuZD[]A\A]A^A_SHH(H+p6k .AŅt/Hcу^L .I|DEAAA D9tYAuD[Av6Ll I1DH1zeH5Q .H|Ll IAFDIILA?I AtPHw H=Qc f\UHLd LHHE 3DOuHÀt*u!HHtxju,HRj 1tuHaj 1t5uPHGH8Z12. '.HcǃH5.HL H.HL .t/HcЃH5.HL H.HL .HcЃH=.Ht H .Htσ wYHu HcH>Hi Hi Hj H-j Hc H=j H]j Hc H3c PHyv H=oa H4i H|i UHVSHH= QqDfBGt kCHALH)H@AщHf@f{t {uHMH%a H1rH;u={u7`tHc H1SrHd H1;rH;uH\f}yHMH3d H1rHZ[]HpATIUSH薅Hŀ}tBHHbLzH@tHC(H;C0r HzHPHS( HK(H;K0rH߾ []A\PHqHs( []A\AWAVIAUIATU1SHHtH1HHHҍj}xI HMtHLH5/a 1vLL=)-贄IApA@HE 7AtAAuEX MPEkZ BlD9v"EHLD$D9DCDMLD$HJ+L1LI^LH)Iʼn)I@kDAm [B+HH[]A\A]A^A_SHFHH+FHH4HsHKHHxH)[AVIAUIATMUHSL1HIMu HI0L@HPL)H9s HLH)LHPHHHoHxHHHX[Mu]I$A\A]A^HdH%(HD$1 Hr HcH>@H=4.Ht$EAAD\$@H= .Ht$AEDT$.HcL .MD1 H .LD1At\6.H .H=.HHcЅx9H4H4Huz.Hq H=\ yHD$dH3%(tHHcP DDLATD`UHSHHHuCHCKD9ɉKHcJHC@uLCIcA48[]A\ÐLG(L;G0rC.H=1-AuHUH5e19A@H-JMHLO(A.H-zJH=-E1% A=AEA_AAE9_APw q_APvREtAw,A`w#E1t_Dc@A`v*AowEtApv 1_E1A_Dc@DD_E1E1E1=_HW(HLLkBt%bH{IdEIkHshDEuHt_McA9bD9bAhOw DS$Et6AJLcIk(HsD&vaD9Jab% 14aALaAMkB;W8hed1ÐsD_HcHHL 11H軷SHV(HLHcŃ+ILL)MtI} LKKHSxHLE1fE1ft)PL>HHcHk(HwD+hL5$HcgLHA hkDLkLChE ]iLkBiHXjHLjHkHSh:?kH{p H=n 跇Hcp H=n 蟇IkEkEIkDD;W8NmmH_hAIk,3HX+( ;llHkHWhI4$1H4$EDAAD;N s=@H4$HOhHk1Á9 Hk)H 9VuLcMk(LWEG8ACHw(H|\Ht$HT$ L$DD$wT$ >AMkC4p% 1X[]1HkHGh1RHkHGh!Hw UHSHPH?OmYHHH[]AUIATUHSHQH?oHH;H AroH;Ɖ9uZH[]A\A] LDXH[]A\A]AVAUATUSHPdH%(HD$H1H`v(HD$HdH3%(HPH[]A\A]A^d AՁ`wHI H|$ DDd$ HD$ H9$uT$(9T$uD9d$,| L]HtD9oAfx\KXuT[GL(IDh EHLHckXID$1DmDkXIIIM\$[Ld`HcLD` H{xLDI8HtLOMtLWC| rLD ]NH{xHuCpHCx DspD9|EDspIcHCHCxH[xHcL$HD$HdH3%(tHP[]A\A]A^с9t HkHGh+HVɋAUATUHSHL"9t HkHWh ΁9t HkHEh0A+4$I|$D,HD_HtxtEl$ HD^H[D]A\A]HGHÐHW1Ht HG| Ht#D#1uHkHUh OIkH}hDHk21CATIUHSӺHPA4$dH%(HD$H1H=H9,$t1(9\$At$H|$ H9l$ u9\$(HL$HdH3 %(t6HP[]A\ÐHw UHSHPH?iAXHH߉[].WX1tHcHt` HOxHtHHHdH%(HD$14$HT$cHD$dH3%(tHÐw SHH?~hHHL[H+AWAVAAUAATIUSQ9t HkHohmDA9t HkI\$h9\%9t HkIL$h E1MtE1A9T$8s11L`Aʼnށ9tLkMD$hA8 MA9|$811L`9EDL \DLH\IHtN}uMtCAuL9uL9u2HA9EsDm LD[HEw LD[IHh ]H=f DD)?AAA9t MkMT$hA*AAA9t MkMl$hA])1Z[]A\A]A^A_ÐHXHt0UHSRG XHcHH{x1HSH=-H5+g 1HcS1ۃtHHUHX[]HxSZHЅ[1AVAUIH5e ATIH=e UH e SHe H@dH%(HD$81H}e Ht$~D$HD$H\$0D$H|$~L$HL$)D$L$)L$ MuL%-Hc@u HI]Hk(I]DCL (AwNLL5@u{Ld MEQH5"f HLARD1P@^K_uRDs1E;u s IcHImHSH5d L1H d HtHMDH5d L1HSH5d L1HHD$8dH3%(tH@L []A\A]A^ATIUHSHdH%(HD$19t HkH_hLH<]H<$HtlOA¾D+EE1HWAODGDNE!AAH d A9u:HcwE1H c t'HI4$tHNAH "HEEEHVH5d P1SARWHASH0HD$dH3%(t^H[]A\AWE1E1AVAUATUSfnG_ o fH~HOHHk(IHD$G$IPLcIk(HHtH9wDqG6MOE1DgdHl$A~L$fn.L|$Mkfn.`L^HLk(D$H^8L$fl[]LnXA\NA]V A^A_LN0L^@LVPH~`LiEpEGtG9tuIAE9wH(@H AVAAUAATUHSHHuH<-U H5Pb H1HU$H1H5Pb 4U0H1H5Ub U81HH5Zb EtIHٺE1H=Rb M9tD9e vD1HHIH޿ EtTHٺE1H=b M9tD9u$wH޿ []A\A]A^DHH$I[]A\A]A^ÐHW(HDw0G4AULoXATU1SHRƇ;kXs;HcŃIL HSxHLL!MtI|$L;CXX[]A\A]u`v PzZÐUHSHPW7H9HHHC1HHHHSZ[]19wuWATIHUSHWLH{HHHnHs8LHHCHCHHCHkHk([]A\ÐHUDATIUSHH?_H;H H>9u H[]A\LH߉[]A\Hw AD$f AV0LM $Lph fE1D_At$AT$?AfA@jA:lIl$1LLc 1U]At$?iT$H g L1DL$YWDL$AFAwF1Dg1LL`*k?iLHIAt$?eiT$EtqLH mb 1VAFAGtE1hT$H db L1VAFEGA@EJE1hAdA@1@u7@u:t?uHAAu>|$NE1jdAD$%AD$MdAD$?dD$5dA@u@tH a L1UAFA_CE1gAt$?hfAt@>@8AWbA/A`H_ uH&` L1tXIv8{fH` L1UXAFA_CE1:gffh/jH8e L1XMn8M]MAFEGA@EE1fE1eLL54AAGffLH_ 1WAFAG;E1f AV0I.xHIljPA@4f@ @xH}j`AEdAW\$IE1H)HkHE9_eEMkMGAx&Ao IAbMHMJAH ] L1VE1cMLEAFAGeAeA`iH] 1L1eViOuAdcLHHN\ LH1)VA+iAviA`t\Hj\ L1TWiAhAvhA`t6H\ L1WhHF\ L1VhH\ L1Vh@6t@vE@=uMLhH=b AuHH] L1/UIv86c1@4@1@C@AoH]IHHMH%\ L1TfAt A8tA>tAWA_cHL@IWLLHD$#AWA_HD$bIHt(LLЄtAD$=eXcHH^UbAw ffh/_AO D$P'_A$_H \ L1PAFEoAEEE1bffheHL@IWLLDL$HD$"HD$DL$A\D^H[ L1vSAFAWBE1[bHL$ag1Ht$xSDxAt$HHHtvL$HHH"oWhIl$I;l$tCLEMMD$Eh{DMfgHT$1H9#}i1H@SHL`f@"^fAG~hHa H=_ !oHt1DDT$ hM|$IOIL$2hMID$ Ha RH=_ nMD$MHML$M8gHCj1HxSDhALHHLHHmjA,$IuiHT$ 1H!kLMhA{0MS(tVMhA.hMeM;et MD$A,$MELi{u A.ujDjk0A?MEWi1H xSI@i@6iH<1H@SHLhf@! i@~jH` H=^ SmMt+DD\$jIELXM]5jA,$whH_ RH=] mMEMPMUIjMZLLH_ H=] lH_ H=m] lHhyHhoH^ H=A] lHu8HHL$HE8At$LD$HxCVfAT$DSDLAA?AE fDSHD;kjH 1H1X Nj@RL[L1LOґIv@LMN@͋HDŽ$DŽ$I)IML$黆A^LD$0A@NM.Mt A}j;A`A-L\$8DCLHdX 1I xOHDŽ$DŽ$LT$0IM+ZIAi󫪪RA`Ht$0FI.Ht }jLT$8DC1HW LI 8NyHL$8DC1HbW LH NRL}H\ b H=Z ;jH$L$ 1LD$PDT$ D\$PljHD$PDŽ$DŽ$L\$8IKAHDŽ$H|$8H@V 1HL`MH$ɏH$L鴏HD$P鏇HT$8$LAUiL|$0LAMguHt$8LL8-SL,HLl$LLH$I~(Ht$8ً$HJFIŅUikH9LhL9$$$D$XHD$PL鬆E]I]AJ4Ht$ EIIm H|$`Hts1 tHH,% $$D 1DL$X髁IdžH{ HwvHD$PÂI1L<xSXLLAHtLHLf tA1LxSHt.@u(L61L@SHHXf@Aw-tL\$0ACTACA9FMt I}ZH9sUH$DŽ$IL$H% Ld$8Av0LLAD$f$fk\$hHDŽ$$5@&@@$$$$D[ID$MT$AL9~IrHH;$LAySL9s IMT$L9u1H]HSHUDŽ$@}$H Q L1EDŽ$|HD$PDŽ$鶁MOdDT$ D\$P?}L<% Et21LD\$PDT$ ;DT$ D\$PxSIt @UkAv0HT$8LA5D,$$ED=DD$X~AA*Il$I9l$HH9$鞀HQ 1L1BGIvHt;AT$ 鯂CCHV H=T dMHV RH=T cƄ$$zEt$Ƅ$Ӄ$Ƅ$tszƄ$@&tDŽ$H :O 1L=CfzH O 1L CƄ$DŽ$6zLD\$PDT$ d21L@SHL`f@zUDT$ D\$PifEt"DŽ$HDŽ$yfEuJAVLE1jH$LAE_AXDŽ$Ƅ$HDŽ$~yHtgHzSu.DŽ$Ƅ$HDŽ$LyfEzHSLƄ$DŽ$HDŽ$yHDŽ$DŽ$Ƅ$xH$1LM鈄H4$F҂H{ǂ$D+tH L DL1`AxHt$0H9^tCtTI|$I9|$t$HD$H$DŽ$HxD$DŽ$HDŽ$$xL\0,$@SHXf@AwHL$0IL+AIAi諪AQHLULL$0LAoAZA[NLEMHLMI龂H]HCHE魂AjLk0LL$pKDjIyeCE8H[;\uFD$ H$XLL.LMIyH}I~AD$`H$D$ AnH\$@~D$@ID$ )D$ Ոfod$ f@0H `E} lHD$`FkHt=J4LL$`D$EaDE9.iA]L,$HIEihH4% A4$A EHD$PMM}HI+|$HI;l$M3uAO4M#uH|$ HuL\$xLT$pLL$hDD$`?DD$`LL$hLT$pL\$xt$HEL}ID$tuTItLt$0MM+~IAi+M'IL}b7_M}A$E1tHQ H=N ^LL$0HދIIl$I+qHIM+\$III;l$Mt(EO,MtH|$ Ht=tH]HIl$$tLHE1:HD$ HxIH$mH|$0D$PgMIzLHL$8L1HsI H @H$LxAAnArAF=Ht$8L^AC)Lok1MD~T$8Im L$$AE0D$Ht$0D)$AHl$0fDo$L`DImHl$IE(Im2Il$I9l$DŽ$HH9$?xD$MMEzMMA{SEtHD$PAIA/HsAG}A~AwhiIHy0LI(MA1cIE@cLD\$ *o]Dd$ H$HmHhHHHsLSI)IwH+sLHHHH{H/H}RH{tH$L9UxHufAF}EH$I aAccH\$@~l$@M~t$`l$ Hl$ AG0IG t$ )l$@)t$ 4fo|$ fDoD$@Hh8IG(EGLI}K $HHL$ 9IEAtI}(J4HIE(EfHDŽ$DŽ$aH4$@LD\$ D\$ HPH$ID;\$)`|$X`A~t~H$ILkLcHL;HM)I茂EKT@0H@(HX LhHPAuD%P-LMuAƆ\Lv(1LL$@SHf@L@ MIaA~2aA^0)aE1A~fAn0fLbH|D$DŽ$t% D$DŽ$ttL{L;{tMGA/LCesJ,AE]^Il$I;l$tYLM]ML$EovA~U_5t]^MMt#A{0IS(tHtA1e[p1eH1e1_M 1__A~dRDŽ$s]ID$SD~$ID<$D)<$kfo$L$$~$@0P\$8X hHIE(vXAA9usFtk~~~`t[HrD 19q~EAH H$E 119N~AH 1HD 19.~HgD 1p9~w1҉9vHkHOH€y&uPHH H=F 5VHH b H=F VHi~DHHEDUHxL]HEMAIUoHrHpIEE1f`\LH`1ɾMRLFD DHP1m;Y^_H}HW IDŽ$H{ H_ULH,H H=E 8UH1HsxS7DhAHHH=DHHH TIELXM]MtDD\$ȁHWG RH=`E T@H5G H=>E TMEMPMUI鮁LMAz0IJ(t+HЀDE&{ĀDc0黀H ImI;mt*LEDeMEE݀{DM~錀DeIuAHT$ 1HI韁E1HxSI@H"1H@SHLhf@n\HSHHHiGGtH !u1HPMxuKK[#HHHT$HT$AuHH=$HfA..IAF.A,II$DE$I$HSDjDHACHz#AHHtфA^HA 1?L"51f #HB#HuN IEQGlfL[HAKI3LCEHLHU1HEI $HyB H141-AnA$\IzI$ ÂHHHOD H=A ;QLA$MT$(Aj0A$nu[I$tk{M$M NH HA L13+G<H H? L1N4I$I$I$?HHLf Hc}D]H5-I$M HElH1H5&A L # MUH5A I$DEH1PM$M$ MtLAI$391IHD$HuA>uH|$HH> 1L8L @ L@ LT$~D$LL$D$A$?A$nugL赀HxXHtsLmX+M $M'1Ayj@oA$t A|$A$huA$h@H H= L1k2{H8HtHHtrHxXHtdHHI1LLHHHst L"IHx2AD"LmXH= L1*1>Hi= 1L7L> LEXAWAVM|IAUATL%j UHSIXH8HT$I9ADTu$u zuHI9uLM*IM9v"AufAtu@$uztILL$M1I)EDDHL$DT$(9t$(wLuIH;xuILHT$|$,HHt$ LL\$HL$Ht$ |$,uH< H0HH8[]A\A]A^A_F?uZFuTATUSLfAD$u:HHAt$H((xy AT$L 1ɾL= H13[]A\øATIUSHHuHHtC0H[(uHHLjNuHk@0HX(LH@ L`HP[]A\ATHLjIUHSH uHXL@0Hh(H@ HX[fM]A\Hx0HP(uH1HtHJHt @q@@W1?ufOfDu HG@HG@pdHE1D9e0HE(HM EHJJ<uHU(J4H<3?/tAH[.u .u/tH\3%>HuH5\H:HH1HHIIMhILIL)HIL9tHH$uELd$IUIL3.L6Ht)f.oLH@H)HLK,A$MMXIAAMA\MXIqMPH9r,>\u'AB\HMHBH9r8\uHA\MX똍y EtA9r>It$(I;t$0sVLFMD$( MHL []A\A]A^A_/LH=c< SM LT$T$Ht$L Ht$:LT$T$l HJ H~:HRAWHIAVAUIպATIUSH8dH%(HD$(1H|$6H1IHD$ HD$9\$H|$LHu?HL$ HQH9vHLHIHT$ LLH;D$ t L5AMtLL蓧t LLdbL1HL$(dH3 %(tH8[]A\A]A^A_AWHIAVHAUATUSHHdH%(HD$1HupE1IHE9wv^IGELJ<1HHHH $HHu#IWH4$HJ<HuA롃1Ht$dH34%(tH[]A\A]A^A_USHRH?t1H;9kvHXH[]3AVAUATIUSHA<$LE<:t tHIM)I}}:LLHIB(uHŋS49S0u,tH{ s4Hs4H{(HC HxHC(DC0LS IL[(MO4AO,DK0][]A\A]A^E11D$D$@ut$AD9AEt$QuDD$uANPyT$HuT$HS|MP~\$A9AE܉\$zDd$zS1Ht H{XH[AVIAUAATAUDSHt HXLsXDkpDct@[]A\A]A^AWIAVIAUATIUHSQH_XGpL,H3HVHwH}xLAׅtL#HI9wX[]A\A]A^A_AW1AVAUE1ATE1UHS1H(DwpHGXHD$IJ40HHuI*Ht%zH*HI9LBHYXD$D$HH9wHD}tHL$IH=Ǩ-H5}6 H)LHD$1I*LL$LT$M<$xI*MLII I*XH=o-LʰLT$YH5.6 ^$lUp1H=@-H5+6 TH=--L1H56 (HL5I] HwHƺHDHCDFuA$u^ztgHH LHHH+>uGHHHukDHA,uHpAA)t-A)u fA|$AtH3 H1"E1Hs81Ҁ})HHNHHhI $EtA|$L4LvAL$E1dIuHH+1LHHEClK1MtCL(L8L \ M9vEPfCQ tIL81LH []A\A]A^H8H0HH)H9sGATUHSH(H)HIH[HHH(HLH0H8[]A\ATAHUH-d[ SH8HHp~HJA@yBDMtHH݃/u%x*uEtH81H# H8H8[]A\HH1HT$nHT$`DZAs@:H!HLBMVE^w\AhIIAD\$1D$0[c{ MD$`H9tXH9tYH9+7G WL8HHt$ LD$ L(LD$|$X|$0{D$Xl$0t$0H(LL$@MփD$8D$8I)AA9D$\r H|$HL4H|$`1Dt$\HT$@Ht$`LD$0L$8HLT$fD$cLT$LD$0L$X{L$02D$1D$XDMAtu D$0D$X|$>DL$XL$X|$Xz*L81LHH|$ v L8IxƃG HH|$HLD$pLT$hQ HT$LT$hLD$p{-D$1L҃D$8H+(D\$8D;\$\+H|$HJ|$X>D$X1D$XD$GrLT$@$11L& HM 6 Ht$H贤A$t\u#{2>z A)\AH{(AH+1ҋG DgMHOTAJI2D EZI LILHAHHEHLAWAVAUATIUSHH(~{dH%(HD$1諪Sf{D$HD$HsL,HD$Md$HL|$HD$AT$f9StHsLH5A$HL$LIt$II9uLLHRuf{tc A4$H H HHHIHL$HAT$It$LHL$II9cLLH1HHL$dH3 %(t#H([]A\A]A^A_SIIɹHPdH%(HD$H1Ht$HH{ L$LHZHt HHHT$HdH3%(t訯HP[SHHdH%(HD$1Ht$D$DHƋ~ȉ1G|$uH΃{,H{ HCuE111ЉC(IHKH{HC({(ЃHT$dH3%(tH[SHHPH $1dH%(HD$H1HT$~D$1҉t$$H|$)D$ LD$0D$82Hu D$<E11ɺHHD$<Ht$H=:D$8HL$HdH3 %(tQHP[Hv[HO@LG@1E1Ht%HtLMZL9YLCILIH MIvHH9QsLLHG@HVHHw@ATIUHSHHw{t4&ҲLHH HHuHL臱u'CH@>H@>H@>H@~@~fAuxALHAAH)AV9AAwAHHHHHHHfHF(fAjLHAH) 9LHHAw*LH)H)DMDHEIL DI؃ID$K "AIDD$DI u DzLCAIDT$LI u DzL"AHDD$CH u DzHHDz@|$MAw(MI)IaEDHDzEHH ÉIڃIT$BtWAIDT$NIu ALAHDD$AH u A HcH A @|$ONALBDzL6H|$XdH3<%(tHh[]A\A]A^A_AWAVAUATUSARLt$@HD$HIHH vi>ZLIBua11DT.HHL HuIIHLLHI1Mt+It$H} ILL*t HT$HM.HZ[]A\A]A^A_HSILǃxuLHP0HLZHZE1M9K HHkHL@I9wL@I9w]LQIHP0HHt;LZHZE1M9vK HHkHL@I9wL@I9wLQIE111[AHHL@H[AHOAWAVAUATN$UHSHXH|$LL$Ht$L$HL$HdH%(HD$H1LL$8H|$HT$(LLD$0HHM H $LM{L\$ LsHtcHHt$HL$(IHt$HL$0HHT$ Ht$8H $LHL$DLLHH|$MLLHމHT$HdH3%(tiHX[]A\A]A^A_AWIAVAUATULSLH($H$`HL$@H$hH$pHt$HD$xHT$HHL$PdH%(H$1$uHt$HH|$PVILI@1L$AUt$_AXL$H$LAP0fE`fEpEHHEPEXT$(LI@(HLfDd$ fD$E`>DL$0Ep_AXAą,H$P1DD$(L$H$Ht$8AL$IL$pH$D$HD$D$tHD$(D$DŽ$HD$hD$ D$0D$`D$XL$L$IHD$I\$09$A~tT$` DT$0T$` DT$0DT$XE.L;$rH1H5\ LL$1H @-L$H4%u:MNLc$IFIv I IAJJF HH uD\$ D $H5 L輑D$ uzIN IVSM$t$ILTZYuH$pD$ {u8;u3H{ H5 YuDSAzI9~ wHSD$HT$hL$ $H5^ LD$IN IVAQLML$APt$IAZA[IF H$HHH$赏L$D$HHHpI9rDH\$(D\$tf$$u|A~uuH5 LWubIN IVVI$t$LM_AXMnL$H$L$I~ L$H$HT$D$0I@D|$XDT$`HLDET$XD$E$EbILd$8El$(E9w1H5 HE1A1Z IT$IL$ ASIILL$8ASt$A^ZL EuILILt$8IN IVAPIH$XPt$AYAZAŅ HHھLnIH IV ID$ E1H$PHT$01HHL$8H$0IHkH41I9t"ECAAAw fA{tIIHt$`IkHLH$HHt$XIH&H$HL$E1LD$`L9@~σf~H9D$0w)1HH5 HT$XIHLLDHD$8LkMIHFHtH9H9wLQII9v HQH)HHD$@AHD$`~D$`FAAHIH LLDMeHHMuH$0LIELD$HMW0AAuMMg0,LIHٺLAA Mt MM$$M*D$0)MIHtIM)uD$0D$0H$HHLHHLH$H|$hND$HHLO,$I!LIH!H5 HII9vJLT$hA DXW< wDX0EDBW wDB0EAHtI AA/IHA.debHHLfAAugH$AAIHLALLExyH$pHHL |$tH$HHL WD1IjILjt$ht$h$HL$pH0HHAŅ" |$ tH$pHHL H|$tHt$HHLHj H|$(H$@E1HD$Ht$8HT$8Ht$褈s$XZAHHLLIH7H|$LH萇HyIHLLL^ ML$I9vAA>/uLIHLLM(H|$/蠈HLPHL1L+T$HLLT$`HLHL$ Ht$ HKH9HHt$HL$`LHD$XH1LIILLHHLHLLd$ Lt$XMtHT$IHLLbLd$MLt$qH|$/ʇHt LpL+t$LE1LD$UH E1LSLL$8LHt$|Y^AąygULALSLL$8H E Ht$OAXZEy9UMH5) SLL$8LHL$"A\AA^DIAMtH|$tHT$IHLLnA8|$tH$@D草ydH5 HAQII1DLL$AUH$ AZA[tYL$L$pALMM9vAID1AE34HHLAH$ D9t$ttHHDCdH$HHL IIDP1Ljjt$ht$h$HL$pH0AŅHHD|$tH$HHLu L$1E1I$@MIpHtIMt I9LOIHH9HLI I9uMtHu<$HH`AŅOVL)ILLL$AQt$ILl$6_AXAŅ<$HH zL$LE11LT$Hu HGLL)HHOAH uM$H$IE1LD$L$HLH$Ll$MMH{LMMu%LH꾴LL\$L\$HItkHLLMHDŽ$ILHDŽ$4$t$LT$(`ZYt&H$H$CLT$H{HSHAL$ZH H;\$)H,$LLMIMD$LD$MA|$Hu H$L龴L+HHH|$vWIl$}uLHuH$LLHHt$LEH}HHHD$Ht HuLL$1E1ML$AIt$AD$I L;d$3ILH$MtMHٺLLAEuHHLE1H$?t$xE1LUS$AAV$x$$h$x$X$hL$HL$PH$(H$0H$m2HPL|$PAAD$E11D$ HD$HHLD$H$sEDd$t HHLDd$H$NDd$EtH$0HHL.EtE1H$PHHL|$tH$HHL|$ tH$pHHLEtH$HHLH|$tHt$HHLHE1<$HHދ<$HE1LAE1AAAE1JAH$L$A$|$0tD$D$ HD$HD$H$dH3 %(DtOH([]A\A]A^A_ATIUSHH dH%(HD$1HGz8Ht8uHk0C89tHRHsC8Il$HSHL$HsHDžxRLKLCPHjjHT$$RH;s HL$8QI $4H0t|$ tHs(H{LD$L1HL$dH3 %(tR~H []A\AWIAVIAUMATILULSHHLL$H1HtBt$PLL$MHLLHAQM MLHD$HXZD$H[]A\A]A^A_AWAVAUATL%ULMSHHHt$T$dH%(H$1Ld$0jjLl$IFH[]A\A]A^A_UHHSHWHvHxFyyHIH5oY[]AX[]HH9r,w%HNH9OrwHvHLF(L9G(| øHH9rwN9O| øHH9rATUSHI@Hl$0HHt$8IHt9HkI0LTMZL9t MKL9uIBH9D$@uM9vIMbCL1Ht/Hl$HT$@~D$Ld$HPD$HCD$0H[]A\UHH?SHHLLOdH%(H$1HD+OH`z1H{0HS(H$dH3%(tyH[]USQHGH9wH)HwHG!o8uHH5ZC81Z[]AVE1AUIATU1S1۾LMetWE$$?wLHH EuH5YLAExA@t?w HHH H1[]A\A]A^AVAUE1ATIU1S1۾LMt$tt0u4[KH_1҅t!OH5_1[AWAAVAAUATMUHDSHLl$PH\$XW)zwMkw(DH MRq w oH|$$H;$ rL1H5fA1hHT$8H$ HEL$D$(H$H$H)HH$H$D$L$DŽ$Au H|$HIAu H|$HH8II E] At.Au]1H@5At!AuB1H@1H@1H9@DžtHD$$iwHl$`~T$`LHD$`~L$L$flT$`f)T$pRL$$$LD$`Ht$PH|$HmH u$tt1DL$DL$ tatHl$~D$Hl$LLL$D$)$P$$$LD$`Ht$PH|$HH t{|$$DD$DD$ t$@AUAWAVD$HAQ$HLL$hL$H$HT$HHt$`H|$XH09 H$dH3<%(tjH[]A\A]A^A_AVAUATUSHl$8HEHt#HkLUM\I9uI9Ku E9CtLIHL$0EHIILʾEH1Ht!HUILoHWHDgHU[]A\A]A^AUIATUI,0SH1HLd$HIL$Ht5HkI$LDIpH9t LVL9uM9huH9vHIhBHL$@LM裼1Ht&H\$~D$Hl$LhD$ID$H[]A\A]AWAVIAUATIUSHH$0H$8H|$HL$0L$ LD$L$(LL$8HD$@HT$`dH%(H$1HL$HytH|$mHu I|$HIt$PMLHHD$ HH\$ s.u>LD$`LD$(H|$LL(iHHP 1H߽H|$@11H|$(D$\L$E1HD$D$lD$XD$hHD$PHD$HL|$pL|$ L$MMLl$xMAHT$HI9WLD$HIwAMAUJ,MKPEE |.$AsXHt$ L$xAXAYiAL$u!IW<*u$u L$LL$0EIoMGw0ww7|1YwUXtn $L$MuHHCcHt$8IhH;n0rH|$H5fHT$8LJ8KLHK'$H$C DEAA$t LD$xHL$pLLH$L$L$Hu5$H;$H$Hv$ulH$Dd$hH|$PXD$EuL$Dd$XLL$t$`AL$LH|$IqL$YAYAZaHEfD$1INj$II1ILII(HH!HLhL;$rH5HH\$@L$Ml1ҋ$D)$1ANj$A1IDAHE1cDM|HoL$E$EWHA\Ll$PE1E15L-)H\$@HL$HT$(E1E1H|$H$HE1L$L$HDŽ$自HL$HT$(H$H|$sE1$H\$@uH$yHL$HT$(L$H|$MHLHHL$LH@HT$(H@H|$H$H$H HLT$LkL$AzL$1E1LHT$L\$H5bMMMUH$ H$LB AK`H$ DŽ$XHD$(H|$L$0L$(L$8$@H$HH$PHt$@HT$HH$8JMl$MMkHL$HT$(H$H|$¨sM$$H LLo HL$HT$(H$H|$AH|$uLL$0Mq`MahMipIiX$Ht$0Lv`HL$0LahL\$0MkpHT$0HjXHuYEt6Vt$`LL$ LD$8HL$HHT$0Ht$(H|$_AXHuE111Ht$ H|$Lt$8ALKLD$ 1II`H9KL,IIkHL9w0L9Bv$IApJHRHMIhI1Lt$ "IELL\$X1A)HnL9Jt-HLkMM93wM9svILT$ IM9Sw M9S vIMM)IMIL9wI[H$ $HS HsPH$WLD$ HL$HH|$0L$0ZY{L$H$ Ht$ H|$L|$8ARE1Ht$ H|$Hl$89Iy@Ma0MtyA<$/trMy8MtiI1LHT$(LLHILH|$HHL$HLuKt.HHLLD(/HLHLILSMb@H[E11Ht$ H|$L|$8HS@AL\$MchM AT1LATt$ t$@LL$`LD$hHt$8H|$(H q,HL$HT$(LH|$BIHt IGE1E1H$hdH3%(tpPHx[]A\A]A^A_AWIAVIAUIATMUHSH(dH%(HD$1uHH_ HD$Ht~VMLMPHLHHD$_AXuh|$HD$t1XHH_ LT$HHt3PHLMARMHLLT$sZYu|$uLT$E111LLHT$dH3%(twOH([]A\A]A^A_AWMAVIAUIATE1UHSHAQHUH3I9s-LMLLHIHHVHvH*MLLHHEHX[]A\A]A^A_AWWAVAUIATUSHHT$H$H$HL$0H$XH$0H$ Ht$(H5'LD$pHl$HL$HLD$0H$L$HH$@LL$xL$PHD$8HT$@MdH%(H$1H$HDŽ$H$H$L$D$@DŽ$L$D$L$MMM)$D$H$D\$ H|$ jH$L$LHt$X6H9uLD$ H$LHH$HH$H DDD$hAAv LH5HMMI|$ HtrHDŽ$HDŽ$H9$w L1H5MHMIAsLT$8L AD$@L$hH$1L$@D$`ML$H)L$HH$@LL$PH$XL$pDŽ$xL+HtD$LH L2LLHt믃$HH$HLLHLIH$HLH1LLl$H$HD$ Hl$P$x6H_IHLHKHL$PHD$`cE1ɅtEMH$EE1H$@DT$lH|$PHtH|$PIHMuHH1dHT$J4LL Ht{L$MIHLLIMt D,DHHLML$D$`DL$lLD$ L$M A@EH IhIPHD$ MMLt$H$HVMLLH$ Ll$H H$IH$H$E1҅tDULLxLEHHK|$ L$hWWH$($D` L$~$xH$LH0H+t$XHt$)$HL$P0HH@@H@(XHH@XH@`H@hH@pASPAVAUD$`AP$PLL$pL$hHL$xHt$XAH0t$8LMHuHMILHUPLMMLxHLx9LMMIEu(H$LLuqMMMMMLLE1H$HVH$L;$s$MkMLLIJtHVPHHmD$ L$H$H fHL#LLLHHLt$(L|$L`Me HL$pH|$xHXHHt$@LpH$(LD$HLx HD$0L$8HJ0D$@A}Hz8HzhHB(D$ Hr@HjHLBPLJXDR`uI] HtIHI$IUtMIEHtIH$LWD$ LH$dH3%(D$ tFH[]A\A]A^A_AWAVIAUIATIUHSHI ME1IMIM9tB\C BLCIN|%1AL\$LHAL\$~/HL9t'HE1IHM9tBC<B<CIIMM9uHu-LHHL8HSIII)LHI:HE1ILL=M9tBLC4BtC ILIuHHH)L9rLLH[]A\A]A^A_AWWAVAUIATMUIOSHIQHGGHC @tXA GHC(HJE1IIDBDrt JHB4H{(B47IIuHC(1@t I俰IDC8Lƒ1HAoA LD @k8LHHqHHAǃt+u-H{ t&H_uH{ AHC AZD[]A\A]A^A_AWHIAVAUATUSHH|$PHT$dH%(H$1HA(H$hHt$ HD$FHD$HHT$Ag8=YL-IGIWIG0uEHL-1@H;I1H(Dut3HHuL-K-II?uDHt FI EII?uH|$@A &IG LD$LL$LT$L\$AALl$Lt$ALD$XHT$AH\$HL$LT$xAL$HD$A H|$Ht$ Hl$LD$%@L$LL$M'Ll$hLT$ AAL$AH$H$H$LHL$8H$ H|$pHt$@L$L$L$L\$HT$H\$L$$Lt$A Ll$D$4L$AH$A@H$(D$` D$LL$E1L$ME1H$hH;D$ /$L@H|$L$ht LL$A.w?(Gw v$""C*pH+"M\w?9[!C{G|+^!Ht$PHNI9tEH|$xu=Hx1H9s 1Ҁx\Š@<(u H|$@t<|!H|$Xup!LLeIL]M)IM9vqIu A#ML]IvHEHuLCHEHL9tL)H$HMtIMtIMtIyLc ]L;D$ H|$xD@HPA\AH9T$ v H|$@tH|$@*#1A)u MH#E#x)#/H|$Xt A|\ HQ EH :|? LLeHLUL)HL9vgIMLUIvHEHuLgBHEHL9tL)H$HMtIMtIMtILc 6H$E1E1MuH$H${H|$+L$hA ?A L;T$ t`IJH$hAHt*tH|$pt)\u.H;L$ IZH$hAZHt+t?tL$hMoECH]MHuI)II9HmHHuHvHEHuHDL$HDD$(@HEHOH9DD$(DL$HtH)H$IMtIMtIMkIcH$hH|$ztHL$9DQ. @A.A9uWH9T$ vPAtJH|$tH|$Dw D۾ D9u!H$uLA$ L)fAD$EA$E)AfEL$E1ILLeHLUL)HL9I'MLUIvHEHuLDL$HDD$(?HEH L9DD$(DL$HtL)H$HMtIMtIMkIcLcD)AI9t HD DKAfAVEH]MLEI)IM9v_IZMLEIvHEHuH>HEHFH9tH)H$IMtIMtIIt$M9tIA<$A|$fAIE1AFMH]MLUI)IM9vgIMLUIvHEHuHP>HEHH9tH)H$IMtIMtIMtIA$IL;D$  LuMLMM)I"M9v_IMLMIvHEHuL=HEH L9tL)H$IMtIMtIMH]LHuH)HH9vgHHHuHvHEHuHB=HEHH9tH)H$IMtIMtIMtIH$hIt$I?^ƒA$H$h8^u HH$hL$hLL$0LeILEM)IM9vgIMLEIvHEHuL}MtA|=@\"L$tDI9 MFL$hAFMtAD‰D$HDC<4@]uH$0HrI9ENt!@-uA]tH|$A '5F@-uaMVL9T$PwA~[tOIFH9D$PwA~[uA~^t6A]t0LD$|$HMLH$H7uRD$HE^A-uMA~]tFI9LD$IMLH$HL$hz7tH|$Ai4H$fA:@[@@ I9.IL$hI9 1DL$hDI9IVH$hEMtG\A:uA~]t"H9t<tLD$(IG\Ƅ$pƄpA: A~]H|$(H5H$X7H|$(H5$7H|$(H5$7H|$(H5}$k7H|$(H5$S7H|$(H5S$;7H|$(H5A$#7H|$(H5/D$d$7H|$(H5$6H|$(H5c$6H|$(H5$6H|$(H5Զ$6$@ƃ$$AD!΃|$dAD!փ$AD!ރ$AD!ƃ$@!$!ƃ$!փ$!΃$AD!΃$ADH$Xt$tH|$A1H9IL$hI9wL$X $A$1ۃ$Aui9LA[uJ$uP9LADXu0$u69H8_u$u'9HXtDEDAG $u8H0D^uJ$u8LfA<[x0|$du8LADXu$u'8H8D_@tDDDC $ur8LAZuM$uY8H0D^ u4$u@8LAD[u$u(&8LADXtDEAE  K+ ()'= 19 <3 `~  B W{ ?wb {|l%H|$@(QDT$4H|$C4t$`Hk(0HD$H LED$41H$Hk(H|$L)HMt LL)HM\$LHOM)Lo_ ILoLuMLMM)IM9vSIwMLMIvHEHuL0HEHcL9tL)IMtID|$LA$IAD$E|$D$4E1E1E1L$$H|$@* |$4H$ MCHHHuHvHEHuH[/HEHH9uH]MHuI)II9w$H)H$IMtIMtIMtIMA$IM)AEAfEE|$4u-H$g H|$A( MtL$4D$4E1H}Hk(HT$H LrHH $MtNl7LrDJ IA D|$LLRDL$(E)F<H]MHuI)II9v_H|HHuHvHEHuH.HEHhH9tH)H$IMtIMtIDD$(E|$IE1AD$ED$H$. H$4 H]LLUH)HL9vgIMLUIvHEHuH^-HEHH9tH)H$IMtIMtIMtID+<$I\$L9$$tIA$AD$H $fyMtIAEM)AfE}ILeHL]L)HL9v[IML]IvHEHuL,HEHL9tL)HMtIMtILcE1E1L$$kH$Z{ I@H$hAHtPЀ w1A~L$hL;D$ uAuE1Ek ET:<,tEcH\$AH$hH;t$ t?LFL$hHtHЀ w AAuE1Ek ELAuAEE9H|$hu:<\H$hH;D$ HxH|$H$htH\$<}Mu2H$ uH|$A %%D H$MA~H|$A $ EH]MH}I)II9vgHHH}HvHEHuH*HEHH9tH)H$IMtIMtIMtIEM|$E)M9tIE $EL$MA E1fEF(AA INLELHuL)HH9HHHuHvHEHuLDL$dDT$HLD$()HEHHT$(DT$HDL$dH9tH)H$IMtIMtIMbIZE1AMAMXLOdMM)AI9t H@1@qAfEVfEfM` M9t IAACfAE1AFfEVAEAyA@ MHE)fAx LM`AL)fEP M9t IAAYAE1fAVfA~H$u'H|$E1"Lt$ L9$hAA H|$hL$h{H|$8MH]MLEI)IM9vgIXMLEIvHEHuH'HEHDH9tH)H$IMtIMtIMtIA$IH|$8W1MH]LHMH)HH9vgHHHMHvHEHuHY'HEHH9tH)H$IMtIMtIMtIA$I'H|$8H]LHMH)HH9vgH'HHMHvHEHuH&HEHH9tH)H$IMtIMtIMtIA$IH|$8H]LHEH)HH9veH=HHEH=vHEHuH/&HEHH9tH)H$IMtIMtIMtIA$IH|$8nH]MLUI)IM9vgIMLUIvHEHuH%HEHH9tH)H$IMtIMtIMtIA$IgH|$8H]LHEH)HH9veH=hHHEH=vHEHuH%HEHUH9tH)H$IMtIMtIMtIA$IH|$8DH]LH}H)HH9vgHHH}HvHEHuHo$HEHH9tH)H$IMtIMtIMtIA$ I=H|$8H]MHuI)II9vgH=HHuHvHEHuH#HEH)H9tH)H$IMtIMtIMtIA$ IH$ DCED;T$LvH|$AD$4HxHHT$Lk(F;THuMH]MHuI)II9vxHXHHuHvHEHuHDD$("HEH?H9DD$(tH)H$IMtIMtIMyIqA$IED$H|$px)H|$t LT$A)MEK|LI9ur@tmL$hA<*t^<^tZH|$pt<\uEHA+tDA?u <<+t8I4HH1D7ALDHIDLLHSfsHUuRH|$HLUHHLHM7LUHMLLkH`H)HLHpByLLA8 ~Ht L;uL_HRL;EIYH9pL9`AyHC-<:L; H`L;p HI9 A9<:LZL;H`L;ptmHI9tiAH -<L;HIyH9p,L9`Aq<1LCHpBLL;H`LPLH8L;HL;IqH9pL9`AAH-H`<L;pLHI9cA<@@8mLL;pnA9 @@GHLz8.ICHًuLL)MIL<@LMID)L9^DkD,A9W D6IJLHHHHI)ML9|HH$H`8msCISHL)HLMLI4HH1Lc}D7ADIL9IDLuL9LAL9P@L;p!΃L!A8t1HEH9E0M9ՉuML}ILHMIDAt$AL$AT$I|ItILI9r"LeM$L'II4HH1L{D7ADL}HID0d\LL9PLHpLEI9wtHHE1IL;(NH}NLeNOL]L}E1IL;(s0KHK HJJ L8Lu|LDž0EuOH|$HLMHHLHMfLMHMLLL@H)HLH8L9HEL`L;MtH`L;ptDHI9t@A H5-<}ILEH HpOHp~!H`0' YHpBHpO9uYH|$HLHHLHM!LLHMLRRHpsDH)HLLI9A HL9LI9A HHp{a3 HKHMC{HHtHu>8L9P`EIIE9LMHXC89u(t/HII9uH8H9t!HH`HuIHuHuA3A HLLMHHHBAA>JH HIFI IFHMLMLEX8D]AAEX8HDHH9LMD(LAEMI}J4I AuI}IEH4 I}IEt HLM,L9H;pD)H=m-I9MDHDžxE1HDžXHDžHDžHDž@HDž HEHEL=-LL9L@IDIH}A1HtZ<7 tjtA HU< tS}t)ILEtH}uA9u1LI9rA H@ tu L{L}CSHHLHM9EH} sCHKHM^L9pHEH} DIK]L)HIHD)H9PHHH]H;]tH[KtuS[HH 9H@HI4HH1D7LcuADML9MLeAuCH|$HHMHHLLMHMLMLL…L)JLLLHLL$ DXDPAEHt$ p@HLHD$ HD$ L9^8LHLL$ 8HcLPxHKLcIL\$ LpADu*?8LOLL$ GD_DHHDHD$ H|$ I9wLT$MLT$A:IrHt$ErABAAIBMcHD$B|0LT$EBEJAEMcO2M9sYA:umLDXDPAEIcHD0HI$ArEZDLcIrO2M9rLt$HD$H91Ht$ A:AH=;HcH>LLLLL$L$H ULt$DpLLLL$OOTL$Lt$AуH Ju ǃ AkLXL\$ pDPDHLL$ DH@ADHLHD$ IHH9t3AHAAHD Mt@AA<2 @ ÉAL9vSMt HHLDMt Dۃ DۃA HD19v[H -H= -%ҊG8tG8HNLFÃG8HFHFHRAQAH1APA1躸H(鬸PAH1RAPA1rHdQB8HуiȀB8H -ȹHc1t H Į,HZH-HuHH1SHHt7 -H1HHw -HHHqH D-SuF1O-H&-Hu HU0H-H-HuHL ,I[H1HHE11H=-HLAH1APjAP_H(vPHcH,IHH41HHHMtL9vIHHBDHHSHH?!HWH{ C c8H{(HC HC([HЍVNwcLMc M>AHuJHuHt?DW(D;W,}5HD$~D$IcAHL$HkHG @DW(D$0@1LGHEARtAOu/OHARu  IOHH1LGJAUL-7ATIUHSHQHtGȃNw>IcTL>A$ HK9uEHSHLH[H[H[X[]A\A]AUATL$UHSHQL9taHDmu.ƃHHH@HǃHHHPHD,DX[]A\A]UHH5ySH8dH%(HD$(1HH]1HHHHHHQ7HD$(dH3%(t H8[]ÃuXUSRHoHuH9sHHH?HHuH;WHCCHHkX[]ATIUHSHBHHtH;rvHy{u H{LH;HHHHSHk[]A\HE1_uHƸHs[]S1ۋG(;G,},HcHHkH_CGAHHCH[SHH1҅HsHKHcH)H9}1HHSCt :$uHHS DC(~qH_GLOBAL_H9>ubDNEQA;wTIMsD~ Nu>sH~)lj{HD9C,~IcADC(HkLHS HLBB:D;C,\IcAHkHS BDC(H:HHrBHS@H[ATUHSLg@HHC8Bu'HHHCHKHHHLc@H[]A\HW:SHBHGBt HJHOBD@A v<_t DHAvp1<_tXE1D@A w Ek$ATp@_Ek$ATA9MHOuAHAHG<_u9W8#H0HDWE1AAu@tHwCDFLʦ,MA8Ip(DO,Ht7W(EP01D9}%HcHkHO AW(HqDQHO@Et MXE@ MXE@w(DGH1D9}%LcIkHG @w(LXD@HW:BuBSHHHu1){8;{<}HK0LcJщ{8I8M9$[1ÊH'vAHcULmu LS!IlL9E!IEeM)IA_A}_A}UMuE1L9AHЀ w0DxAw7 DHAwWIHIIIwa<_u]HEu.ƃHHH@HǃLIRHF,D[Hu.ƃHHH@HǃLIvHF$3MDMnHUD H5 }HUDAuH5|HXHu.ƃHHH@HǃHH~H3.ƃ.Hm}Fc H5q|HpEHߍpH5]|HNHm$LT$0LmE1L(I HLJ(LMA{EEL(MjA~ L(AHMABfAB3wII IMtJMmAu>MmA}F H DIIIAMA׃3A}uLl$HL$H D$)D$HUDH0A}u$Hl$H EoMMIB| @tEuoHu.ƃHHH@HǃLIDHIRHJT,8B ƃ QL(YLpLmHpL(HLJ(AtOA}uHA}uAI}H5Szu(HUDH#H5~HLDHuXHu.ƃHHH@HǃHLfL3 ƃ Hu.ƃHHH@HǃHHUH+>ƃ>L(Lp>8t$H5rx[HuHHuJH8/u8D<Ex,EtH@AH8/tH@HrL HDHML L Hu+ƇHH@HǃLIUHB+~ƃ~ H5w&H5nwH5fw@HUDH$H5_w H5SwH5PwH5RwH5RwH5EwH5Fw~H5PwmH5Ow\H5RwKH5Xw:H5aweHUDHIH5ev H5FwH5KwH56wHcUHuH(Ht+DrEuLREAKD9HE1rD8HEEu68u4LPDX1MA9LMII;AE1DA#tD;Mt1A$uHP E11H1L(LD$H Hl$L(L|$D$ Ht$(HuHUDH|$ uHDHLd$L(EL AHmuHcUHuHcUHurEA tDH(HUHUHDEAA@LL$L(HHl$L(L LD$D$ LT$(L\$|$ L(Hu.ƃHHH@HǃHLiL ƃ gEwYL(L H|$0Hl$8H(ALt$0LD$@LT$HHt^LXE;AAwMxuBA DH(AH)\0`Ht0)d@HH(@HHUDH|$@L(AtAMDHIHHT 8}H(HUDHvHT$H(DHl$H(L HUHD$D$ LD$(c|$ uHDHLL$L(f}tH5qs2HUH=p,H9ztdDH Hu.ƃHHH@HǃLMeLB+ ƃ f}tH5rHfH5rHRHUHtDkH}6HHv&3HHH@HǃH5yrH#HUDHL@LL9@HL9HHHUHmHtDHu.ƃHHH@HǃLHDHIKHB{ƃ{PHLmH5qEe.IEawYHu.ƃHHH@HǃLMHLB ƃ IuMcB| uAIcHn H5pHHUDHuF H5plHpHtH LD$HD$L HT$HU:t*DH"HpH|$H HRDHHpt Ll$L uZHu.ƃHHH@HǃLIl$HB# ƃ Hu.ƃHHH@HǃLMwLB;>ƃ>%HUDLuHmA>1MNH5M)Lu}uLUA:u L]A;)ID}8u"HUDHLDHvH56nLADžu;HH H8/HxtzAH@ރ3E1sH5mLru`E1}/uGLuMt>A>Ju,IvH1Ht8/uHxtH@AAHmHuDHLDHMHu.ƃHHH@HǃHDHHPH(ƃ(IVHu.ƃHHH@HǃLMGLB;)ƃ)H5zRLuHDH H5-LHu.ƃHHH@HǃHHHqH (ƃ(L]A;8HUHJH1~cu@>DwAv%r@vHMDHu DH Hu.ƃHHH@HǃLDHIKHB<ƃuYHu.ƃHHH@HǃLMGLB;(ƃ(LMH5jMQI:L]ISu):u$HJ9)t ǃ0HRDH DH LmIuL6H5LHu.ƃHHH@HǃHDHHPH[ƃ[L}IWG Hu.ƃHHH@HǃLMD$LB#]ƃ]4H5^iLtLDHo H}DHWHHm}1 LMAyp MQA:>b MmMǃ0A LmA}:uI}?;uHUHMDHs LuHmH5hMFHELmI8LxHhuQLDH6LDH LDHHߺH5ThHDH H54hHI}tgLDHHu.ƃHHH@HǃLMQLB ƃ LDH, HHDHLLEE1A8'MHEiE AvALUA:=uVHu+ƇHH@HǃLIKHB-ƃ-HUDHA]A)H5cJcH>Hu.ƃHHH@HǃLIoHB;uƃuHu.ƃHHH@HǃLMt$LB#lƃl[H5FH~BH5$GHe)H54HLH}?uPuJaH>HUDH"Hu.ƃHHH@HǃHL_L;]ƃ]IIIUHDzA+A(RA(JIBMjABMmA) A)RIL(I fABLHLHH2H9tOH9uL9uEHRD;\IcH AHDXLHHHHHpHHt:8/s<etH@Ht8/t H@HBE-L !MwL L A놋h;lLGLcIL`hMGL:LH?8DH(HUH߃H$dH3%(tH[]A\A]A^A_USHH(dH%(HD$1HtHՋR 4=~ ǃ0GHHH,$UHꉇ4HHHHHL$Ht$HHM4HD$dH3%(tXH([]Ã:1uHBHcPHpR@ATAUHSH!wew4woHRiO) )&*w.#\$H5]%taLtqw,+- H5]kHUWNtLOtd H5H] H5D]H[]A\-H56]H5/]غ H53]H}u!aH5 ]H}EHu.ƃHHH@HǃHH~H3(ƃ(HUlHu+ƇHH@HǃHHQH ƃ HUwA|Hu+ƇHH@HǃLIl$HB#*ƃ* Hu+ƇHH@HǃHHHH ƃ Hu.ƃHHH@HǃHHVH3&ƃ&nHu+ƇHH@HǃHLGL; ƃ H5hb H5ZQ(tVHu+ƇHH@HǃLMHLB ƃ HUDHH5cZDHHu.ƃHHH@HǃLMZLB)ƃ)HDH[]A\[]A\AWAAVI AUATAUHSHAPH0}HUEup3w IHMEL H )uHMHDHL q*uHMHDHL M)L(HRDHHǃ(L(AuH5VHXHu.ƃHHH@HǃHHWH;.ƃ.HmL}A?Fu< H5VHEGHApvH5UHMI AA3wMIMtMLDHL DHDL HmX[]A\A]A^A_AWIAVAUIATIUSHAPMA{IS wHH1uuMƊ<(ta tXHu.ƃHHH@HǃHLGL; ƃ Hu.ƃHHH@HǃLAMQLB (ƃ(E1L(1LHǃ(HEtXHu.ƃHHH@HǃHHNH3)ƃ)Hu.ƃHHH@HǃHHPH(ƃ(IUHt HTHu.ƃHHH@HǃLLI}HHB+)ƃ)hL(X[]A\A]A^A_AWAVIAUAATUSHAPHuDHƃHHH@HǃIHȋhu-HPE1:*t1H5SHARHHuE11LDHEtXHu.ƃHHH@HǃHHqH )ƃ)HLGL; ƃ Hu.ƃHHH@HǃLMQLB [ƃ[IHt DH.Hu.ƃHHH@HǃLMkLB]ƃ]X[]A\A]A^A_AUAATIUSHQ0wHCHrZHu.ƃHHH@HǃH1HqH (ƃ(LDH5uXHu.ƃHHH@HǃHLGL;)ƃ)X[]A\A]HBH:f1AWAVE1AUATUSAPH LaLiA<$;u Mt$Md$D<HLJ<@r@R@L@lt @rt+H5QLLHLHu+ƇHH@HǃHLLGL;(Hƃ(LH`H5#QHHu.ƃHHH@HǃLLHMQLB (ƃ(sLHH5PH(LHLH8Hu.ƃHHH@HǃLICHB)ƃ)D<Z[]A\A]A^A_1HuHtHHwW1HuHtH2wHW1Ht#HtN1wHwHW1Ht#HtN1wHwHW1AVAUATUSHHLOdH%(HD$1LxH1H&IHLKHA9Fu  IIMMAQwH,$MPIhM.L,$MH$HtnD[8D;[<}dHs0McAJD[8X APЀJwAH jJHcHHkH$}I{PH1 aH-s,DC(HHHD;C,McIAD`MkL[ ACDC(A'ICL$DcHLKIHLK1ɾ(HH#H$*H H$HH$IyH{EIA_A0A wYHKLALCQ0 vI)DS(D;S,IcALkLk AEDS(EtzIEI}EE$DsLCLHDDsLIHuGE1HC8_u;HHHCL*HH0;IHLKcIHu1 HOHtHL+HH$S8;S<5LS0LcK‰S8HDs(Dk8DcHpLKA9IuBH$Hs8;s<HK0HcHHH߉s8rH$yHkDs(Dk8DcHdAA0HD$HSEtHH{@DC(D;C,IcAHkHk EDC(HEL$AHEDeH}DPEZAH =AHc4H> HHCC(;C,|LcIkHk EC(M\HE}LeJLu)HHHC3HHt+H肸Uu@h@lt@t1L@LCxlHHHCIHLKA9EIHLKsDS(D;S,McAIkHk EDS(EC8EELe;C<|XhHPHSxtuZHHHCxFK(;K,}>HcHHkHk EK(HEC8EG;C<}LC0HcI,C81HS:BuHH[]A\H[]A\AWAVAUATUSHHdH%(HD$1HGS3 NtUZHHHGIH1H1I IHCD E;ADu%D@HAATu AL$в%w LHH҃At$@v tASu2HpHHHulHfAIuHHHHCX DATu H腶*AEu I.HuwAMucHt^HHCHHtHHHvASwHk}EiHt{8;{<}LS0LcKʉ{8GIIHuAuQ0EtHXu/K(;K,cHcLkLC A@K(AFE`MhMA?uMwA>)uIFLLHŰIMI@xtt1辶AIZHHGs(1;s,})HcH=QHkHS s(HHzBHHHCHE1ILKA9IEtIHLK MDS8D;S< Lc0McAOiAHHEt}CuwH DeAL$3wIII*HmAI LMA 3HHLMQLUHK@1@@EIA8 w%smt,uiI@AI8LtHrLNv>BM@Mu74w#MIMuAtH@Hu1M@1HHEu}u 8)uH@HHH[]A\'H[]A\HG8_u HHGt1HW:ZuHUSHQHWCH{?.Oq@wLGEEQAwIA_t_t݃0 IA8.tLLCk(H);k,|)#EXA0A wIA00@ wI1)HcHkHK Ak(tHHyQH¾MH6Z[]UHIHATISHH`dH%(HE1LEE@LEEEHEHHEIEIC KDM̉EHLkHUHMIL)HH9tHH$At L)JLIcHIH IHH)IHH9tHH$At L)JL H}LEHeL.Ht?DAsw1McM>AH@H@؋H xA<$1H]dH3%(t膢He[A\]HG8LHPSHHWH_tZu1H#|Hu18'uHp~t~){HLC<A8nu I=LCHSLKEAEtEtILKMˋ{(I);{,|10HcHkHK A{(EtHtHHQDYHH营Hs>EPHHs[1AUATUSHHLg@dH%(HD$1HG8Eu3HHGHD$dH3%(H11Ҿ/[]A\A]H$HHS LtMIwMHKXu>HDkLCLHHSHsDkL>Et1[HHsH=HHt1H¾/H莤HEHtH{Hh?EeHLc@H$H{HL$dH3 %(t[H[]A\A]HGQw HHG1HGLuTu٧AUATUSHAQsDPAru`HHG'HI3LKIA9ItHLHnLHH蠣LHApHHGQ1ɾJHfu{xpHxH{xTu HHC1HȦPDC(D;C,BMcHAIkHk EDC(EHE;QЀ vouKxnHHGHHHHs>IH]HHittuMxluGE1tu HILCAxIEHLCL0H|H1IHtXDA1u?HHH5:QH)SHHIuu/H7L6H$A2t:A31DfAtCEt-AAD`AEu1L5Htn@}@pt@mu>@:}u8LCA8_u1IE1LC%HCE18_u9HEHHCCE1H5*H5u H E1HEtHH¾8HHL6HLAycuEEZAvArAv}fuHIHI H_IH5 *H萞uEHHeH5+HktH5HXu4HHHC8Iu+HHHH H HHHL8HL7HHH5Y)Hڝu HMfu,HHHnHIcHnUwt a_HHHHsI@>@Eu H1HsC@pu!~iMHHHsEg@i,~l"HHL;HڞH:HʞL9HAXH[]A\A]鯞ZH[]A\A]AUATUSHHdH%(HD$1HGH$@80u3HHGHD$dH3%(H11Ҿ.[]A\A]CAHDkLCLHDkLHu131H¾.H HEHtHSHhD8"uHH$HSHT$dH3%(tH[]A\A]AWAVIAUAATIUSHHHGDUMT$D}L$ MVLn'IzI~AruAFH t$ 1AVuAFH t$1AKuAFHD1Azu1MBMFABAFH HwǀHsHtHEHC0X[]AUIATIUSQH_HG H,H;w HH9w LHAՅuX[]A\A]W8WtGe;s0}E1eEUD;S0}E1eesP2fDSP)fD9| IHs@It7HLdA)H|1IcHwLcc0Hcs0\dD6DurdHUs,~ HHPH{`HtzuH{hHtluH{@{(H{8sH{@sH{H|s{p4LMQ@MtHAHD$dH3%(u>H(H[]Bs1H{xH,H=F,LF,L 1>,LE,L 3F,L|>,H>,H>,H >,H5 ?,H=I?,Lr?,L ?,L>,L F,LE,HE,HE,H E,L?,H5+F,H=,M,L?,L K,L'F,H?,LK,HK,H?,H @,HE,H K,H5/@,H=X@,H5QE,H=BE,LK,L @,L@,L@,HA,H@A,H iA,H5A,H=A,L4@,LD,L D,LD,LA,LD,L A,HC,L B,HC,H C,H5D,L B,H=iD,LZD,H;B,L DD,L5D,HVB,H B,H5B,H=B,LB,L #C,LLC,ÐfAVHAUATUSHHHT$Ht$HdH%(H$11HH| H9/HwH9@n/trHwH9-n/t_HwH9n/tLHwH9n/t9HwH9m/t&HwH9m/tHH9m~/uHH=j,AHt$H|$Hl$HT$H9Jqt$H_NIH=bD,1H=TD, H=%aPpyfHtH5#bfSfHtH5L%C,L+%C,IiH=C,H51HLLC,LC,MJL C,M)HHIL9iLH=xC,LL5lC,H5]C,MI9hHjC,L SC,H=\D,L%-C,MHLI!L)LL)H9MGLC,L C,P=C,whH5H= D,PL5C,LF[HHxC,-Eb,/iL-b,MhL%b,Mvf=b,_f=a,8f-a,d=a,od=a,d=a,gc=KC,c=:C,d=a,eHHWL\$HI3"L5{@,MM.Ld$ LL_x"|$8uLZbI^HL3LL^x"t$8uL>ZhH[HL+LL^x"T$8uLYaH[HtLL5gL+LL=^x%DD$8AAuLYaH[Hu=A,HA?,ux=P?,buDH$dH3%(uCH[]A\A]A^ZhH>,Hh`=_,`Z'baf.AT1I1USH0dH%(HD$(1HHpULHH߉_HL$(dH3 %(u H0[]A\IZfPH=_,H)H5_,YH=Y_@PH=_,H؃)H5_,YH=I^@H)a,H)H5^b,Tb,H=]YWb,HPb,^HfHTd,)-d,)6d,HSd,V\H?d,HtH+d,HH@HHd,Hd,HH1HH|HH9t/uH=^,\ff.AT11H==,UIH-s)SHHLH yԍ1LHH=,H+=,IIII9vLH=c=,LD$LD$H=e=,HLHH]LN=,LG=,HuL;C=,uH==,蠎L !=,MQL=,AL=,H-=,L9u 0=,L% =,L<,L<,HL<,JD%ILL!L)H-E)HL)H9IGIH<,H<,1LHL+<,IIIM9vLH=\<,LL$LL$H^<,Iu*HHHH]L C<,L <<,HtL8<,HHLL; "<,uH=;,L<,MZL;,AL;,H-;,L9u <,L%;,H;,L ;,JD%IHL!L)HH;,L)H9H;,L];,H9H};,LSLr;,L`;,La;,M9u ;,H-f;,L O;,H0;,M$(HLI!H)LL%&;,H)H9L% ;,L:,M9H5:,H^H:,L:,L:,M9u ;,L:,H:,L%:,K,IHL!L)IH-:,M)I9<H)H-:,L@:,H6H=w:,fm6G4H5g:,HH;5d:,H5U:,uH=/:,躋H;:,LSL0:,L:,L:,M9u K:,H-$:,L :,L9,H9,M$(HLI!H)LH)H9MGL%9,L%9,H[]A\HT$~D$L9,fl)9,H=9,  LL$~L$L>9,fl) k9,H=O9,ڊZHV9,HG9,L9,H=$9,诊f.UHAWAVAUATSHXHwdH%(HE18 FMH})E1H })HxHr8,H5})HHLHAH H)H) 1HH LH=e8,UbvH=2,1H5H7,1DvH5(H= 1,H7,VHNiH5HHU4i1ҾHbLo7,1HLHIII)MIL)IIL9tHH$Lҁ6Ld$H5 ILLCRLspecf@sVjL- )MIuI}ISnM9uH=ߥsH=sH=zsH=nsH=bsL= 1,A?0uH5/,>jH=.0,?fH=8,GfH=0,?liH=0,?iH=0,?0{6H=(/,?jH=/,?iH50,>0uFH=5,H55,Hi1H314tAE11ҹHH=.,DH5/H=5蒧H5H=L=5,MIwH=.,5THo_1HM`IHHsH=l.,SH:_1H`L3MtyIvH=2.,SH]1H_M&Mt?L-.,It$LSH`1H_M$$MuH?4,HtFL=fH[Ht+{ uH3 L€uLCI8q̃= 2,C4H=4,Ht2QL H5h1jLH =LZr^_H3,L 4,MyLMM7fEIOEA%E_IwEA%iEwIOEA%tiEoIwEA%5EgIOEA%t5IwEEA%uHHNYe%uIA@{t @<"ALiEE< M}A< AE "UA7IO@ @%E_IE A%EoIOEt A%tlEgIE\ A%EWIOE@ A%t8IEE( A%uHHODAE A%uIEOA{t A<p ALiEE< M}A< A  ;*M"Mf.AFM~<{tk<IAt<;u!AFM~A>;M$MAFM~<{W<<OIAt<;uAFM~A>;MMAFM~<{F<<>}1 %tJPL@;t#t} %t+IAt;uLEф @IAHI@{<WAx{zIx1gEAFMf< M|$A< AE * A$Mr @ L$LrEu2HDNH HVBIEQMf%AAvfuIL~HUL}M)A*L]A3@ @ }upN,~f}H C,IH<@Lt @IM9t7ILLH-uB<+uAu}tAGIM9uLeE,$E=AD$A|dA&ZA:HE;ZR}%.HLX;}%HLX;}%HLX;}%HLX;tttp}ts%HLX;tUtQ}tT%tvHLX;t:t6}t9%t[HLX;tt}t%t@IA t;uxIKHMHt z;ZIIA[IC{<WA{{}uI{譄iDA~u}tAFIL;u*SA~tAFIL;ufIx1EHEIHAEMU< < MMGAEMu< < MM}f;LeE1*L}IDELEA H]9fDfELeE1A*Lu@uLuL]ILuEA LE8fD@W:IvE1L}IDEnE1L}IDEMA}{AEquI{;IÉAEMAFIN< < MIdAFMN< < MMLEHEH}t ;<IAfLeE1A*!@}H}H}L]HH}A3@  LE8@MMLK\IL9KI>LL(uA~tAFIL9uMMMoAdAGZAD$I|$<  <  MH}*AD$It$< ,< $MILAFMAWK8IMIH vH\DII9I}LL'uA}tAEIL9uM MAEMAD$IT$<  <  IHUAEML}PM>AIO[J\fIL9I>LL'uA~tAFIL9uAIK4IH\fDIL9I>LL&uA~u}tAFIL9ufLeHMAFM.AFML} I\DIL9fI}LL4&uA}u}tAEK\DIL9I}LL%uA}tAELeLuE1 MHMAD$MpAD$MLuE1!IL @J\@IL9I?LLe%uAtAGK\@IL9I>LL-%uA~u}tAFLeE1IHEAD$ILeE1IL@J\DII9KI>LL$uA~u}tAFIL9uIIzLeE1kMR91H5,,L%,D.EV2H5 ,L=",>n2EE'EA A _Ei2AwIG@ @M2AIG@ @12AWIG 2AOIG tt2EOIGA t]E1EWIGA tEE1A_IG t.1EoIGA tE1HD(A uIDHLhM)LuA;NEo1EL}MA fE_MGLEA tA;jE-1AwMg@;tq@ tk@1AMg@;tS@ tM@0AWMg t6;t10AOMg t;t0IA $ uDD)A!HuLE1MH=X,H)}AEAD,DEMDUDMEL-,A;]uIuH}HcE}twA;]uIuH}Hc!}tSHcME L}EHEMAALD;cuHUH3H}tjAHD;muMEL}E $A u EL$M|$A;tEE/E"ML}_/MMM`L}MAML}Et"ut}A?.E}EeM}EA /DM1LH=,{L}MASMgL;:IMEI)I32LIMLHH,BD(I94Lw,L5h,MMtH5gL .HEdH3%(He[A\A]A^A_]Ã}DeMM9A?:zIOI9A:t:IOI9A:t&IOI9A:tHI99:uLyQM9:,HYDQI9A:,HYDAI9A:,HYDiI9A:,HYAI9y<:k,HYDII9_A:O,HYDYI9CA:3,HYqI9(@:,HY Dq I9 A:+HY y I9@:u:HI9uLE;M# 3LLeA|$EPLLHH/B3:H HtH,ELvM0MILMwH)HLAWjB)LM}LuLm?HUBLb< ..HULMAAMa< .-LMAGMo< ))HuM)LE)H])AGMw< ))LE)AGMo< ))AGMo< )**AGMg< O*F*n++(+++H}++))2AGMw< 22AGMw< 94'4424fUHAWAVAUATSH\H=o,HPH5*bdH%(HE1 H=+H%++9+WH, t}HLHtt tiXLHtc tXpLH@tQ@ tExLH@t>@ t2D@LHEt*A tLH@t< tIAuLD\A87LPI{Pa 7AMMkPO,/tkIHDHH4$HD$.@ILHcH : D$D$Dd$HL$(dH3 %(u0H8[]A\A]fHV,H&9ff.@UHSHcP{Hc,HHHZ[]fAWAVAUATIULSHxH +L=+H|$@HT$XHD$8HD$HD$@L +LL$PM,D$OE1D$NH,$HD$ H|$_H|$H|$P,LH|$8HHD$hMBLt$@LL$XMcFK|H3I6IH/HD$`HD$0HHH؃HD$(HMHHL$_LHt$IHr HHHE1At DADAtBfBIAt FF|$N)KL5HH|$(HtA?@9HL$H4$LALD$HUE+uAIHI;I9HHthHtVHtDHt2Ht HtHVAISN 6O 3IN6O3IJ 6K 3IJ6K3IJ<6K<3IJ6K3IM9(N 6O 3NT6OT3JL6KL3JD6KD3J|6 K|3 JT6(KT3(NL60OL30NT68OT38I@M9fDHD$ Ht$HHHD6E0DLfEL|H|$H|$0I9Hx[]A\A]A^A_À|$NMOD5 H1+HT$HH +HL$HJHH=AAE{&H|$1H51gHD$ DH|$.H|$PHD$01HD$`L H|$8HHD$hMu6Ll$`HT$0LT$@Lt$XL9LCMcZI9K|LBLRIHl$@HuH+MH|$H$H$D$NH|$HD$ HD$HD$uH|$XLPH|$8L=+?H+H|$H\$8uz%>A8TATED ADD+H5HHR%1H5AH1L1HIHD$1H|$81LI1HD$8H|$1HHHHL$ HD$`HD$0H|$H|$OLGH|$8L=+6H+H\$8y$AtftDH|$H$LH|$8H$$AUATIUHSHdH%(H$1IcL$I<$HtHIHtDDMcl$AL$IJ\-$At$H}1H$dH3%(HĨ[]A\A]fDLLnILL\L\L)HH)HHHfHHAHQHI]I9AHHtmHtZHtGHt4Ht!HtLGAMENOT INO\ IJ4Kt IJKT IJK\ INOD II9NOT N\O\ JtKt JTKT J\ K\ ND(OD (NT0OT 0N\8O\ 8I@I9SfH}HH[DL$AA@B(\\Mcl$DLfDLMcl$d@AWAVAUATUSHH|$@t$T$dH%(H$18+k$111eAą{#Ht$HT$ _#HT$PHzPT$PDHH^HŅ4#HcD }HcHH$HIIAD EA $LVDHLIIIt|ItTIt,ID)EA #D.HHD1EA #D6HHD9EA y#D>HHc< [#HHD!EDA :#HD&H$f. #HnLALHMA8@@ "HD @}HEA "EPDIHHuEA "EXDUIHHuEA w"EhD]IHHuEtaA W"EpDmIHHuEtAA 7"ExDuIHHuEt!A "D}IHHuH;L<$A< A AGI_< A \AGI_< xA IA< uA IA< t< t< t<#{<%u |$<:< LfA:tA lHDEuA:PH9$j!DsA 8!A .!IM)AmHcLHIcHHr HHHE1t D>AD?tBfBIt F F DLcA\$A$< At$ MT$؉ AT$@ MT$@ 'E\$ ZIA$AL$< u"El$ IA$AL$< t< t< t<#phA<$M@u0fIA?@t@ uA@ t @MM)EFIcWLHIcHHr HHH1Ҩt DDtDfDHt DDIIEEEt2A\uA#IIED$EEEuՀ}*A$HH=4AAEKLmLL%i+HD$AMuuMd$ME;t$ uI<$LuMt$;+M.H&I|$HMt A|$% DL$AD$%HEL$$h}A< '< *< "<#D< t< At$pfA toAGI_< < < I#@ -I  M<#OA II MIc< < uf.A I5@ @ ~@A TA 0vLA MuI@H=x+H$dH3%(H<$H[]A\A]A^A_KH5vN@Hs1L1 LoH+H+HLILLHIPIpIpM@I@MM`IIpMIIIMHxIPHMPM`I9uL=+L%>+HR+v03LI#D\$MD$L-+I$H"/E\$ MD$AD$%ID$Ml$ID$(L%+DEA EHIr AT$6L ff.@AVAUATUH~SHchHIHcLHr HHHE1t AtF fF It FFH=+AHu;(1?"H +HH+DKEQDSNd[]A\A]A^Ë+D[EkD9uр{ff.AW1AAVIAUIATUSQHH=e+HHLaDHu\H[H9k uH;LuLSA>+I*t]L"HsHHt{%uhD{$C%X[]A\A]A^A_H +HHHyHqHH9uH+yE^H"~BX@tIv1H1KH!뎿0LHj!L {+HSL,HDc HSC%LCLKHC(HJ+ff.fUHHAWAVAUATSHH5,HdH<%(H}1H€AH5f-HLAAE5H5N-HLAAE H56-HAAENHEdH3%(He[A\A]A^A_]ÐE1IL-b)Ot%E1LH5,HIHtKHxH5,AHt0HxAL=,LgHtHxAHEeIWILJD IH%I)IML9tHH$L9uAt L)JLLl$H5,HIMHILHI)ILH;HHNI}HH9HHtlHtYHtFHt3Ht Ht L[M]LMDHL MLHLMTHH ILHH<I|HLM\HH9sXLLLLTHLH| L\(MDMLLD0LL8MTILI| M\(MD0ML8H@H9rItHE1At AAtB fB IAt BBMIsAMMHXH5u*H@HtHLHH)LLILHLA(AI6MT$LII4$LK\>L)H)LK\fGLA<$G\>G\< ff.USHdH%(HD$x1H+H@11++++++H++11H=M5+\H +HLHH D3LSExD-<+E1HMdH3 %(yHe[A\A]A^A_]A ub x+Lb+LSP+B+4+D3ED-+ExfDA  +|Ly+Mt=Azt5D_H=!KtAAEu=+EZ aL ++Mt*EqEtPhL +MtAAv+h+Z+L+>+0+oD%+E} $fDE;f.AO)AWMG) EWMGEA)AMG@@)E_MGEA)EOMGEA)AGMG<)tAw MG @tq@)tkA_ MG t^)tYAO MG tL)tGAW MG t:)t5EW MG Et'A)t!MGEEtA)t IE8EuHM+DD)HtpLcDMALH[H_D9c uHH;L+uLs11LDI>ILA8IXht&+q!1eA>AAD‰AG< E1< tEGKMuE_=+C4@*…L ʶ+DWA)@*L I MkKDIMHIAIItGLMLLLLLLHL HNLLLLHLLHHL|HLLLLHLLJLHL\HH9LHLDIM,$LLL4Ml$Md$LLLMULLMeLLHM]0LLMe0LL~LBMeHL9]HLD=i+L=+H+H+z+I9UH=j+LLH5+E+L=J+iH=N+11tLIH=&+11tSL+I{HuH=-+11t*H4+Hݵ+H+ε+HLc=f+I9H=+H5G+LL=+=0+x+LH=+11T7H=+LVoH= +LU[H=dz+tF1ҾH=U11H=?H=+1Ҿ11H=>H=g+H=y+tF1ҾH=11H=>H=M+1Ҿ11H=>q=+H=+foL1H=>+MH ?PHDž )fDž(L+H=HA8H1HM1LH=ҫ+HHQH OH X=+AGH=g<.tLwAGI_<.t OAGI_<.tDBOuAGI_<.t W[I_<.tDB_AHHH>A_t }11H=<L=+ ML5B+M8 EvEOA{ I HH =+l L+MSAPA9EX1AK|fR}7+LkH+LA+L+2+H Lc=ί+M9 H=+H5+LL=+=+d H=Ϊ+111AMAt<%uHLH++LH=+11hKH=+11K.H='+11.L:+L+++I,L+fA.oH +yɱ++=+ E1L\+KH HH9LLHH HH9rHDH9LLHH HyLLLaIt$I|$LHLH~ I|$0LLHI|$0\L: I|$HMT$HLLL1LI|$`ID$`LLHLI|$xIL$xLLHHqI$I$LHLH*I$H9HDM[ MPE;{ubI;IcLDDL=LDDu%AjD@U@ @A;K )M[ MDIcHLۃHLEDED9{uHH;L[AjUAA ED9C 8EEILHD~~HLgz{OL{[L.wQL5j DyHeMDPLE1E1>=g+;H0H5 DDDDH@H= DDL}+L+n+IeL]+LI/dev/nul6+0+MAClH,+ KHcФ+L=+IL-ff.AWIAVAUATUSHH|$XdH%(H$1D$TD$WD$7D$(D$hD$PHD$ HD$8HD$HHD$@Ƅ$A<  <  MuMmHLLt[MNMuzMnD9MuHLLIuHtADtUuA:u |$A|-MNMtM.DEUADt AUqE:( MnD9hLt$(t$@$L$UHD$ H|$8HED$8HD|$HLD|$@D$(HD$ H|$HL|$@AM~<:.DL$TMAD"L$(fD IA<{X<}A<;u E<%uA~*AE tIDD$Pf<}@|$h5|$W*|$ULT$M9AD l$Dl$hLL)|$D$PX=+|$XH5+Lt$HE1IHt$HDt$E)AAAAAtiAtDAtH}LL诺AHH}LL萺AHH}LLqAHH}LLRAHH}LL3{AHH}LL\AHH}LL=AHD9d$H}LL˹H]H;Et$LLEH覹HH}LLA臹H{0LLEfHk0hH{HLLEfHkHIH{`LLEfHk`*rH{xLLEfHkx SHLLEfH.EfHD9d$Lt$H\$E1A>}tPID9=+~2H+K LA{tAC1DIz>D9=+A>}M~D$WD$V4@<&AHT$XH5X1=+m*?EnA 1LA $DT$7ADT$PEM~<;}<}LL$ MtLD$8M9tLH|$8H$dH34%(L(HĘ[]A\A]A^A_DII]HLHZMMMID9fDIM)AD$HcLIIcLHr HHHE1ۨ|$PAD11LWLAAFD$IAFIA_Iw  @@ L$UIWDt$(Dt$TD$(D$WD$7HD$HHD$@|$VD$hT$VT$PF F &BfBID>AD?ҋ=D+|$A>}ZM~t$PDdtEAHD9d$|$u<+ut$h1,uMMMI]DADt AUE:&DAGIW< 4< ,I|$u A<.t$htxLt$(D$AnIv@ t @ ANIv t H~@ t@ Dt$hELt$(IuH9MuM~D$WD$V-D$V,D|$WDT$(AE<||$UD\$D \$D\$7T$TDL$VT$(HT+t$H1HD$I݃t~tLt$L#HT$LL誳LkMeHT$LL腳IMeHT$LLbI9l$Ld$H\$I]LLH-I]MmLLL LKLLLLL$LD$LS0LLLLT$ɲHD$5LkH9l$lH\$A:IH$1E1`D$ID$HD$$@t$Ld$HL+d$@=+~DE1ID9=+^H+OHt$@HJH;uDDtH1LH=D7H+L\$C<&YAE B< }1CFC< u} bC.YC|%)CB<#AEAGIW< t I< H< t< HL$A<  1dCHT$A<)9AE LE1路NyATA1USHH=+1MH+D BHJH\u[]A\À;-tDH[]A\J7=HHtHXfAWAVAUATUSHH+H9+1HPH+L%+L5+M9H +H-Ö+HIH Ζ+HL!HHH)H+H)H9FD+H+EuvD n+EFH+D-_+D5\+H[DkAD}A9ED{E LdT+H[]A\A]A^A_LH=+蚳HLE=ؒ+HW+D-̒+D5ɒ+HDC;ExLED9uuD{WD4VH=+AJ4H%DIDHד+HDxAA DAADHEOEDDKD NduO+Lc=ʒ+H-+Nd(1E1Hb+HHfDA<$-LtDD4뚐%E1C=wHHxAWLcAVK@AUHATUSHL%+I,Uuw8H[]A\A]A^A_@ 1H[]A\A]A^A_fDLME)AMHAtoMqAD=+H=LARAAED9}>AI\E)MO@Od0 HL9tHD:(uxnuGEH[]A\A]A^A_ÐAWAVAUATUSHHؑ+II<(tiH /GQLH}@l@(tADBAu@_A@-AEtɋ=c+H5s1Hf.IM)E^Ic^LHIcHHr HHH1Ҩt D>D?tD,fD,Ht DDDMLuEQME1 @A(IEMEA)uEYMM)AoHc賥LHIcHHr HHH1Ҩt DDtDfDHt D4D4MMDH=?LL$L-;v+fII}HHǭuL+Hu+Df+\+=R+5H+M ;+I)L)+DT$L=+D52+D$|$t$ L$$L\$(LL$0E1XHy+HHj+H FLO+MmM,AzIrAH=0+IH譨L=+|$D|$t$ D5~+L$$Dt$=c+L\$(D=_+D5T+5F+ <+L-+MuNMtA$HFH>HD$-+HH[]A\A]A^A_<-<_@@ 11LALI\$L\$MtMA$AIEMEAff.AVAUATUSHdH%(HD$1HL$dH3 %(u H[]A\A]A^uDUHSH?/%H=+H,H'+H +HtkxeL@HXMtXAxQMHIXMtDAy=MQIYMt0Az)MZIZMtA{I[M[MtA{~H(HH蝨;+3 H;HH(HP@HxHH[]Éd+f.AW@AVAUATUHSHD'D$D$ D$D$A @A  /A!AA,.DEL AfCAEhLAA\A$Mr EI@IE>HAB*mM@LD$LD$H=u+IpE1HuH{LH5HH5HܔH5HŔ|=+H51Qff.@AUL-w+ATIUHHSH8dH%(HD$(1T$Ll$D$!Hw+H w+H)H9HMHr0HI<$AHLFH:IAI9J M1Ҩt A21tE$fD$Ht EDH-w+H;.w+Hw+6L@1HLw+H LD$=ڕHv+H9v+HXHv+Hv+H-v+H9H=v+H5v+Lv+LL=HHI!L)ML v+M)I9eL nv+H\$(dH3%(u H8[]A\A]ސMItiItWItEIt3It!ItML$ALJONIO,N,IK J IONIK<J<IO N II9_ONOlNlKLJLODNDK| J| OL(NL(O\0N\0Ol8Nl8I@I9@AWAVAUATUSHdH%(H$1HH0-(HHCHD$ L=(E1HD$EAAMM/AEOHAH{LLAI`{4D9zAAtAMM/AEOHAH{LLAI`*4D9)MM/A@EOHARH{LLAI`3D9H{LLEvMg`3MD4$D9MM,$AEL$HAH{LLAI`w3D9vMM/AEOHAH{LLM$63$DrD9.MM$A@EOHAtVH{LLM$ 2D4$AD9MM/AAEOHAE_DL%+DL$Ik0IHD$IT$H2Hw1L14H{LHH$a2H<$MT$IrH=1L1H{LHH$'2H<$辊MD$Ip H1L1H{LHH$1H<$脊IL$Hq0H1L1膯H{LHH$1H<$JIt$Hv@H1L1LH{LHH$y1H<$ML$IqPHtYLd$T$T$L11 H{LHH$61H<$͉D\$LA+ACHHKD"H0HuAI`A95H$dH3%(uHĘ[]A\A]A^A_莋L%'(KA|$u AtHL1L1L$I ]H{H4$HHD$0H|$L$M$MucLH|$ LT$L-Ll$ L$`DAUATUHSHH~t1?uH1[]A\A]fD} LeID$I9D$ HPHIT$:LerI|$IL$ IH)H9HsCHtD Dt DTfDTID$1E H[]A\A]fLHWHHLLlLlH)H H)HHHHЉMT$ML$ IM)L9Is%AuaMt AAubMl$E H HI J|+K|*IzHI)KLL)HHË37DDDDDEB\+C\*Bt+fCt*f.AWAVAUATUSHH|$(dH%(H$1=lk+HD$Hl+1HT$ql+HHHT$HHbl+譈HHk+HHH)l+茈*l+ l+HHH98.taHHH9x.tKHHH9xx.t8HHH9ex.t%HHH9Rx.tHH9?9.uHHHH)5k+Hk+H|$Hk+j+HǀEH {k+L *3Lc=el+L-fl+IO\=L\$M9HT$IHIM)IA;@L|$I M9MiIt~IthItRIt.uHHHL)‰b+Hb+b+X[]Hff.H]c+ATUSH@11a+a+a+a+a+ya+Hfa+qwa+Aąu`EuSH-b+Ht&MtH5FH|H腀 H5b+Ht~t []A\D[]A\ff.fAUATUHSHH~LnMH}HKIHTIEHrWLLjILL\L\L)HH)HHH |u_H1[]A\A]f.HtDDtDLfDLf.H{tE1@H;1Ҿ{t11H=E1H{Z1ҾHƤ11H=趤H{DFl%:HPH9AHHI}I9HHtmHtZHtGHt4Ht!HtLAAMEN OT IN O\ IJ KD IJ KT IJ< K| IN OD II9rN OT N\ O\ JD KD JT KT J| K| ND (OD (NT 0OT 0N\ 8O\ 8I@I9뢋12||DHHIIJt-MeD.A/}uf.AWHcAVAUATUSHHHHX_+H@uWub1H=1H6_+H<1H _+HlHu=11H=͢L^+ADH[]A\A]A^A_HhHtLeMtL-IE111Lz1ҾLH=X]+uaHLeMurLDHэq]AMEA/IA.uA1ҾLLD$LT$A.1ҾH=\+f.ATAUSNHÅt$H-^+Ht+HuHVuHwEu2[]A\HmHuտ6sH]+HHPH]+EtL%]+MsH ]+HHHH}]+ff.HGAT1ҾUSHH11H={vYH{1Ҿߠ11H=Ϡ{v3L%H|1觠11L蛠;kr[]A\AWAVAUATIUSH[+Ht$(HH=Z+9u H?At\yu Hst>yu Ht%<1uH<tH9/=^+N\+D-+\+1ɺH5H=U+eH=n^+H6kH5iH=U+9H=B^+H k=^+H=V+qD9-[+u5/u,=Y+~#1H-I$<H9Y+H[]A\A]A^A_H=U+H59yu#1ɺH5H=U+{zHD=Z+E7H-Z+L5|AEA)AtlAt3ALHELHAAErHHELH€LHD9@HEALLHAAELEILLDKLHD€HHELLكH€I@0LLAYIh0HAAEAYIhHD9S1ɺH5[H=S+yHHvH)T+LL$L T+yHELHAAEt*H1xuD։`AuHA9&Fff.AWAVAUATUSH(HCZ+HDZ+H)H@ONS=5X+E1fo%HD$LZ+HZ+ILY+DHtEDUL-Y+|@LH;Y+HY+f'LY+MvL=Y+ILY+MI>L=uY+L-hY+M)IA ''fE H-=Y+H]H2Y+M.ILsL%Y+II)LD$HLisHH9D$zHHtAu@uL=X+LH;X+HX+'LX+ILX+It I>!L=X+AD;%V+LM9A LYX+HD$ILHX+Lt$L5V+ANL=9X+tM)I'-'fAH-X+M>H]LHW+IrH=W+IH)H|$HL3rIH9D$HM/H LmITHHTH)L-W+I)HHHH{I7AHHHuI9-L-QW+@M]H L]ITHHTH)L=$W+I)HHHLLKMEIIALEH9MItqIt]ItIIt5It!It MULUIt=Ht=HIL=HL=HM\=L\=HIT=HT=HI\=H\=HML=LL=HL9s`MD=LD=MT=LT=It=Ht=IL=HL=M\= L\= IT=(HT=(I\=0H\=0ML=8LL=8H@L9rL=U+(@EDEELDLL-U+L9"AL%U+H5U+ML$I9LU+L-U+LzU+K ILL!L)IH pU+M)I9BH UU+H(H=jV+[]A\A]A^A_+cE\fD\L--U+pEUDUA||L=U+GALfLL=T+0LH=T+L\$L5T+L\$LLLLT+L;T+LT+sH'S+L|$A'LT+Nt:ILT+MHH=WT+HT$}H-^T+HT$HHLHGT+H;HT+H9T+'HHtmHtZHtGHt4Ht!HtMGALEONT ION\ IO,Nl IKJT IKJ\ IK<J| II9AK4Jt ODND OTNT O\N\ Ol Nl KT(JT (K\0J\ 0K|8J| 8I@I9뢾H=S+BL#S+pH=R+%HS+fUHAWAVAUATSH8D5Q+dH%(HE1EfH=hr+L%Q+0MEl$EAUID$AMTL ͸LH)HHH~HtGHt"H0LAAEHH0LÀHH0LAAEHL9fDH0ALL€HXH3LLHAAEHH0LL€jHsLLHCAAEIHCL9sMcHIMWMIL)HH9tHH$H9uAE$H\$HAE9E\$M|$MEkEl$KDIt$H=up+Hu~EL}E)u11ɺH=1I+nH/LdO+ID$MApE1ALBO+L=DEUM IqHtL€MMIE9hw5o+Do+HN+H5p+E0H=L+,\HK1LAIH@AL9HL}E1E1AWHMAZA[HHAzH'N+H9tHH$H9uAQAQHL$HT$LHHUW=n+pL= L+MLE1dZL]C σDOA|Dgn+EH=K+HIE9HCH8H;;t gH]dH3%(D'He[A\A]A^A_]L)JL[A|$At$DMH=M+AAJ4HlDfA0HL+DxD L%L+0`=i+AEAt ~A;5=+=Ym+H=J+H{A=9m+h=$m+H-L+H5n+H=xJ+YHK1LAIH@AI9IL}ARE1E1AWHKA[HXHAMc̃K+HNMIL)IHH9t%HH$ApE1At L)JL<HT$DLLMHHUTO=l+HEL=uI+MUfLsu/I>vguHe]-d=0M+H H+>L[EL]LM=M+M)t*:yH5xH1hH H+IIUHuAWAVAUATIUH=SQpIDž1ID{HSME1H L1H5HL9t LIcDD9~EHcDvIH ;-u{lt1HLH=\HHt guZL[]A\A]A^A_Ð@SuHsI+Ht(H;^H[HQI+HtH;DH[=K+H4I+u[H=cH=%R[cff.@SHHHdH%(H$1HgxD$%=u HcxH$dH3%(u%HĠ[Ã=i+tHH=Z1udDAWAVAUATUHSHLMMA9EAD)9w1H[]A\A]A^A_AyF41E1u}DE1p H}AH4HttD葠A8HEDxD 8`ytf1E1Au ADCDLH4E1Mu1AHEA D0H 1ۉEDE1HE{EE1M9tODNDID`fAWAVIAUATUSQL/LMuf1ۅtRE1E1H4HU8IDx (`Z[]A\A]A^A_AEEe1%D)9vA}B,&ljI>‰H4Hu81žI ݉(H wC'E1D1EE1M9t/OTNTII11E1D`R=4H+H5/H+HHk(L H+LI@ILH9AL9AEHVH IE1IfnHPfnPxLIfnfnX(HHfbfbflM9uHHH9t8Lk(LHCTI9s#Mk(HCLB H9v Hk(ED0DX1Lk(CTHH9uXf.DAWAVAUATL%m(UHS1H8D=t$L|$ MMLLH)HM,HIKLmHLH1Q4H^yLH)HvlN<+HIK4MHLV4H6HY^yLH)Hv4M,HIODmIMI0AP4H"^PMIAMk`HMEi4MLL$IrL]uGL\$B|-ACBfAt*Mt%t$pIҾAWIDEщL\AYAZH{Hk`s(At<H{Lk`GTH{vCHk`AD|$MIHLHCL&Lc$A ƷAAu AdBDL}0HHDŽ$L|$xH;eHHH;{wt&D⋌$$HIHHH$HHHDŽ$HSG{zDEAAD$Eyɷ$wDŽ$9{|dDŽ$H.+Hl$`DE$L3H5;'L^Lc$1HL)*K4HA~CHHQLH$LLA~CLHL] LOKeM1HDSXAEjEMcL[PH=yT+DMk C43H^LsPAFAVFt 9$8<$GC8>fAVUSH HT$HH $~$HHDfl)$LIJLt$fo$~L$k8S L$C C<H []A^ff.USH8H$H9HL$~D$HDHt$~L$fl $)D$ ) $GJfo$fo\$ k8C[ C<H8[]ff.@AWAVAUATUH1SHHHxdH%(HD$h1De8AT$uH=R+t.u%1HL$hdH3 %(]Hx[]A\A]A^A_Ã}8 JM8{@}<It>9{|t9Ht{XLcUF\#fF\'-ff.(@AUATUHSHHHGDEtlH[H)AHcLIM I+MH9yI}HHE1IU"B| PDEQDIE9H[]A\A]HT${(HT${fAWAVAUATUSHH_HuH[]A\A]A^A_ËG$H@Dg ADg H1HLeM$MG M+GHHHrLcAM9IHLE1Mo#B< E$EZE$IE9E@OFtfDUHSQHHCH9C HKHQHSHuHFZ[]ff.SHWHHpH9pH9p Hpǂ[ATAUHSW(LOIHCH;C HHHK@0H_[]A\AWIAVAUATUSHXdH%(HD$H1LA1AIHt>@I4MI)ЉDŽ HI9wEt*MH\$HdH3%(LuHX[]A\A]A^A_@Xff.@HGHHBH9BtH1ff.@USHHoHHCH9C VHPHSHHAH[]AWAAVAUAATE1UHSHHdH%(HD$81yH=yG+H=mG+ILt$1L1EH=5G+HL$ AEuZHT$H5 G+L"Ld$ vufoD$foL$ EMHt$8dH34%(HHH[]A\A]A^A_AH=F+vH H9tAչHLd$ 1u&HD${H=lF+1҉DH=;?H=BF+ 9AչHp7>H*H="{ff.AUE1ATUHSHHdH%(HD$819t#H=E+AAH=E+DIOfLd$)D$)D$ viH=~E+HL$1PHT$H5dE+LÉxLl$ v7foL$foT$ MUHT$8dH3%(Hu?HH[]A\A]Ll$ 1uHD$fod$ fo\$e]H=6==AUATUSQHH=D+It^HD+E1HfH{Ht7Lo?tHXH9uMtAEZL[]A\A]ÃIHXH9u ff.HG(HtH;G t HH9G0s1_ff.@ATAUSH= D+5H=C+މŠH=C+DH賠H=C+[H 1]H A\H RfSH=C+u[H=C+11[pAWAVAUATIUHSHHHtTDk%D9t>DcoEO4dAD$ICN,3JD3AEHmImH[]A\A]A^A_À{xmE1E1I<$1vI<$IHkHHt=OL$ AMx|$ I$xD `Eu I$S1HAuAEE1MkM9tBoLBLN\N\IDhf.HuHdB+Ht HHUB+g4HH)H=uH/B+HH=%B+8ATIUSHHHHHH+@H=L@L8IL@M9qHXL0Ld$~D$IHI!HflLL)L)H9Ϲ2LLG1IL@L8AhiLA@HM` A@hIPHLH[]A\þH(HT$apHHHT$1UHAWAVAUIATSHHH(dH%(HE1n9HIH@HH%HH)H9tHH$mLt$LIMIr"L1HMD=M>HH9rM >LE1At DAEAtF<fG<IAt BC=L%9HHHL@L)MA L(HA$ L)H%H8IL@L9.pHXL0IIIM)IM!LL@L)I9pHzH1L8HHHǂH)HLuHLb Drh~EH3fAflfABfDrhLc(L5O*HrHHCCAT$<ƃSS0lBLHFDxA5oL`L;6L9toL9goAD$HdCHoLH褟oLMofAd$߀s ]@nHH6nLA{tH"FxuDE0cCLCE1HfDcL#LIt$`HHǃM|$PHmCMt$HI|$0L3Mt$(4L;0L;HLe~Ufl8MHEdH3%(He[A\A]A^A_]H)HLHHL@C& L(CD&1Od&HA$ L)H*H8IL@I93mLXL0HKIL)L!IH@M)I9mH8H12Lb HLu~MDbhL3flfALrHL5*fAJfDbhHs(HCCV<ƃSS0?LHDDxA5mL`L;+k@ukL9tHL#cCCfCIt$`HǃM|$PHkCIT$HI|$0Mt$(H 2L90L9HLe~]fl8MLLHf E111ҾHHtLL'MM9HAрs @HHzjo3LiL@HHLLDiBfkxjDAWAVAUIATL(UHcSHHHHHH+@H=kL@H8IL@I9xkHXL0HT$~D$IHI!HflML)M)I9ȹ2LG1HLHkL@L8HV HFDvhHfAHVHfAfDvhL{(CCEoxu[ff.fAVL5*AUATUHSHHLcPLk`MiEHSHH{0Ls(HU,H;0v_H;HsVH\$~D$fl8Mu H[]A\A]A^LLHAHHE1[1]1A\A]A^H(HdAWAVAUAATUSHHDgodH%(H$1Ei@iHG(GGP<ƇSW0=DxIA5iHHAAL~*L @H<$DŽ$%<݌H= eHc,H>@DAT$H-OjMcIcBDM<<$Ew$AvKABTMAуA)IctED9dL$0H$DT$EH$LD$(MEH|$HL$ Aut DE%AH=dDHcH>@EsAFIC80N$0HXPHA H-D$1E11DT$ D$AAHD$HH EH9BE1HCLMuf"L$L$(f '.DT$ A CAEcIsA ADt$AqM֔I?H 1HA HD$ LHH9 IDD$(fMH$8D$8IIJD$HH$0MIHT$`D$AIID$L\$pD$@Ld$xHL$h1H\$X1D\$PE1DD$@LNfDD&LG$`ASHcL%hAH9IHHH9u„|$Ht Ht$`H$8|$8t |$P@$@|$(tDD$@D$A|$頚DMsM;AELM;H@<L$x5HqLHh x_H[M;MMPM9|uE?f@YAm1If1H,$f$@ $$)$0AOH$@IG$A{AoWM_Ao AWM_AoI(JIwI wMGAm1AG @AGIOIGAGAGIc@$LEID9MDT$@DLI_D\$8AwAwAwAwAwAwH|$HA o$AWL$H0D\$8ADT$@MGAI|IcGD|EIE9I'IOI OMGIGI GEO AGIWIGAGEOMEDT$MDAAAl$wH^Lc4I>ALI(M9PxD`LLX(DPH$WIwI wLuAEII Lt|$0AD$7<$Ew$AnH-bAsTMfIt|$7t|$0t IDžM9HMWM WH$HdH34%( HX[]A\A]A^A_A1f)MIEDT$DŽ$EcIsA0E1.E1f0HcH$D$@D$A$$)$0AGH$@I<5Hk(u LEAHAmI]fFAGA:GlAog)$0I_H$@I_IWAAA AH AE111AH\$8~l$8I_HT$8Aw AEwl$8AwAoME1D$|MGIDT$@IwAWD\$8I_EOLD$XH|$PHt$HHARAAA[ZD\$8DT$@A IGI_IGAGAGA7<$]AEw$AN Ic̸H-`AAm@KuՊHH IL H@8t As5IIHHIAkIWI9WAIwI9wAE!A0AO EAGI_IGMwAGAO%MMU?AmI1UAmAHT$XH9T$HH9\$PAD M;M;ƔA`1A}f$AE1E11f|$A*I@AJIIIAE1EԑfAHcL%AH9zIHHH95LxHAHA49BE1QEoGIwAowIWEOMGD)$I_H$M)$DH$IOIA_HT$8HL$PH|$@E\$Xu0I@>ANI% HD$@HHЃaH|$PHT$@@t$p@H|$8H|$(D$D\$x!LLD$hWHT$@Ht$8L$0H$8H|$ LD$`HD$H)HT$`AH$H|$ HT$8H$HT$PHt$hAELD$8L$H$DL$pEI@D\$xD$HI9AAEE^|$XNu*I@ANLt$HIIAAE8VD$XAw H|$8~L$8$AI_؈$@L$H)$0AOH$@AwIW<$AIGI GMGMOAwAmAoMOAwAEwEuEwEw:A$MOM OA]LA]FMEDT$ED$A AwMGI_IWMOA wA A ӑL I LD$8~\$8H\$8Ew I_AwAG\$8EwA_ p@X D@A.H-ADM&HXA{HHHODADMM9M;TA@PEA9H|$AAu AjA|$LHLL\$ H)DT$HT$kDT$L\$ I9tArm aL$(A t0z|$(-AA 陋D$ L^DL$ I?LH1HLI)߀D^AFhLA]AogI_AW AgI_AWAH-@BЈL^D$ YAtLt$XL9t$HH9\$PAA!A1Ew$EFAAH-xVH\$8~|$8HT$8IDT$HEWD\$@fD$@|$8)$0Q$H$H$HH|$8gH$o$H$)$PH$XH$`D$aH D\$@DT$HAEt;'t|$:D$^H|$t5Au/ A MEt;'D$utA9xA6|$M+<HDUsE1;'sH3Duu@'>tEt ImAt+A`HA\ ;iHuA\lHC{lt.LL$XL$0#D\$ ArAXrfI~fH~HI=IHD$8D$(HI=L A brIfH~HHI?HLH\$8r}HT$(H$BЈT$(D\$(I@qfqfH~H9pq $D\$1D\$@L$(L$8Dt$PL$HH\$`fD$XH qqsH$H$LL$f!uvvtyt逃ATLF1DSDL$ L1lA^XDt%5t0t+trLE1DL1HlT,AWAVAUATUSH(L~HFHA[LE1A?0HT$HD$IGIA L$HH/E1E1E11L !$HcIAA499BE1HPHʼn։4s@ufD @t$O'.A ߀EREELt$M)LIA$MD91۾ ݁A$r@SAA PAwA 8EAH(D[]A\A]A^A_FA~A\LXMڀRKLE1LM/u@3wDKcL>D9lAlLXM,uHHHH!O11MuyH1HtHH@ EMRD9u骎kr.ϑA$sڐA\L@K,IAIM<HMu E4xHAHCLcC<2H9jIHHH{H9u„AE2{u.A$֌H3HSI@ALHHH[]A\A]A^A_0HHG݃|$ t'͍tHl$H+fAtHCHcA<:H9IHH{HH9=D$ AD$ LVDL$ I?XLH1IHhDHL9IDLLHIILt$ MsDIIL|$(aLVD$ LL$L KDt$ L$M^@ Mc(MLA[LL$)H|IHD$L $HHIqHr HHHE1t DADtBfBIt BBH|/LDID$A/LDHcMIHHMItItI)LM)HHTIE1KJIM9r8H(IHt+1LHHHLQHHHI9L MMA$xA$H?Adž1IVHƿEV`AA@AdžLMI1LE LM}(HL$ Ht$|$2H9Ew8HhHpH8DpH|$3sH$dH34%(HH[]A\A]A^A_Ht$H;pHh1HHHHyILyH|$DHL#BHD BH$BT HT$8HFL8[L$MLgI~MI9+L;d$ LLL$ A~AIU(DR8HhDPIAAE|E|IHL$LLHD$2LLt$ M&MI\$L9֐H}HIl$AA|fA|}AdžIHH-3Md$ fHLTX1|$,YLL4$ff.fSHH?*1nuN8@1[HSHƿDC`%=@ǃ[H3HfDSH_HH9H@@HCHHH{ HHCHCH[HH[fAWAVIAUATUSHHH{HC8ChH<$~$flCiHs *Hŀ\?kHs LhH9f  {ADL;fANI?A t A  HWL%9E1IIADD)I?VfHELAF5LXD$@DM*D$<D$DD`EED|$L=ʈAqfCG9EkCA}IMGd fAAkCAUDdIMfAWEkCAuIMFdfAwEkCEMIMFd&fCOAkCEEEd IMfCGfAkCA}IMEd0fAGEkCAUIMFd'fAW(AkCAuDd IMfAw AkCMM Em MDd>fCotEkCIAGdIfAWuMAML$}|$ E&AvLA~HuDU8ILU0I;2> H{(H+u@A6H{(DH 1H @AAv@@l{u{ u{ƃHL$HdH3 %(L HX[]A\A]A^A_fLU L9Us0H{(1ҋG DG<HHHHD+pAAt0f=EhDA t A  HzI?IADDHErI?I0{ $ {HuH} H9cHL;DD$L9DEDD$u LLLI~HA@fEN{@ LLfA~%{H谼SLA~YH 9A t A ^ L_M7IADtLA uDLMAF%A9# AFA>A~{}8HuHH}0H;7E&mHk(DUA@D$@IVIvHD$<L|$=E&A)AF@j{H}NAF=%<wf :% @HuAF>=uHHuAFL}AFE'A=A>IOHMAF A=IL}AF#DAF)AF*LEAF A0@&ILEAFXLEAFE(A:`4ILEAF1"A/HHExj;H0H{(DeA-nA=HHMAFAF'AF(vH}AF+!=XHH}AFFAFAH{u1H'HC(HUH鬣HHuAFARh'HPLHK+LaLeAF/y*4`'HHMAF2A= ILmAF!HWLH*A~闡IL}AFILMAF&HGHEAF =HH}AF${VH9}KDMiAHAEL;M(EAh\MWM_ M9@{M9_AWiH߃A葳L;MEAhIGIO H9{I9OmAWi룋\ܡAx.ILEAF,qAFgA=uILeAFOfAFALHH}AF-.H9DMiAHH}AFHH{B1H#Hu/E{ 3L]AF A;=IL]AF"L]L|$<HLMcLeD$<D$@D$D_HEL}A=LH߹IW,ZHEAFD8A=fA:ȘA>>AFR{!C kA}@U-M)H@ALC ,D腒IFIAEf\MnDD$DD9BAE@~|$fAN HHEAF9LD|$EIHLt$MIHAHEH]DA uHLLMHELt$D|$!+D$@IVIvHD$<Ll$AfDL}fAL$I?A t A  HWL-vE1I7HADut4 t  HzI?DLCD]HEI?%AD$5Ll$,MD$HD$0HLD$,Hr1D$4_ t$4ID$9(@@ |$E4$AvIA|$tA{8H3HH{0H;7H}(H+sO/A4$H}(DH 1H /A$HL$8dH3 %(L HH[]A\A]A^A_@Hs H93s1H}(1ҋG DG<HHHHD+DHACt,ChD} A }LHSHK H9:H3LUt$L9ӻE@t$u!LLLIL$H@fA|$}LUfH #) t  LWMDLCDML׃ uLAD$%A;#AD$A<$A|${8H3HH{0H;7;E4$ADE4$AD$AMAD$A<$w4fDAD$}Hm(]fAL$AD$+LALjEA'A"ARt AR`A8u AuZAD$5Ll$,1HIrMD$LD$,D$0D$4 D|$4ID$D9S@@/ |$fAL$ L AD$A9=!E4$AP{8H3HH{0H97H}1HvH3}LAD$A<=0<<ft<:<%uH AD$9=kHH AD$wH;AD$D7A=5A>8LGLAD$ =!HH;AD$#-AD$)"AD$*H3AD$ <&HH3AD$H3AD$:`HH3AD$1H;AD$0L=p7Aw@.@*m``HH;AD$3lHLHHRL3AD$ EA|IL3AD$,H AD$9=HH AD$L AD$EA>>A-A=IL AD$AD$'AD$(LAD$A+=xILAD$AD$yAD$nL;AD$E7A=&f,A:MA>22A4$A~{H `2JcH}u1HL](HE{`IL AD$ARBh5EA'IRLH*QMiL+AD$/Ay*}`pIL AD$2|ILAD$&A=BIL3AD$!NLLHIRA|$YHH;AD$ISHAD$ A{=ILAD$$}H9K {i@AHǣLUMEAzhMBMJ M9j}M9J2ABiHAkLUMnEeAzh+MZMz M9}?M9zABiD\EAA]h.HH;AD$,fAD$ALU H9{i@>ILAD$-ILAD${AD$pA=uIL+AD$XIL AD$.FAB<"r<'sDD$4D9YL AD$ A9=DIL AD$"PAz"pARoIL;AD$}d鐖}K闔AD$4L L|$,HLMiL+D$,D$0D$4HL;A=LHIW"H1HLOoM9ABiJM9ABiԓE}G<HfAL$AL$AD$R}!E /m&(AWIMAVIAUIATL%hUSH8LdH%(HD$(1I*qD$MAfCDtpkCMA\HUfALtWkC}HU\fA|t?DkCHU m HA\8fAlt"DkCH A\1HfALufDzACA;IE<$"A{t<\+L)I@AL oHI@fH|$(dH3<%(HH8[]A\A]A^A_UACAI*DEEA$A{t A\L)I@AL +~IHEfjA}_I9u A} I9Ȕf}+陔HAzHu鬔QHM߀UX"fAVIAUAATUHSHL'dH%(HD$1I $${\ uH|$dH3<%(u!H[]A\A]A^y1ۃ@UuDAWIIAVL5OeAUATIUHSH8LdH%(HD$(1HD$$I2H$LnHHcʉfANu.uUHEfD'ٖ+9H9IDE$A$A${t A\!I|$@L)kAHGLwI)I9/HʼnHoHsSHtEMDE/B(IHD$(dH3%((H8[]A\A]A^A_fDMELPHILITL)I)HTHHHrH{MuAHHM2I9yHHtmHtZHtGHt4Ht!HtImAIjOL%O "IOD%O"IKT%K"IKt%K4"IK\%K"IK|%K<"II9Ot%O4"Kl%Kl"OL%OL"OD%OD"KT% KT" Kt%(Kt"(K\%0K\"0K|%8K|"8I@I9D{'铔Am(EdDd`ElfDlO{@E@PoS߀UyID$@L)kALpLPM)L9v'HLL$M\$@ALpLL$ID$@LLLHhE'C&M3HA$zt镔USHQHW@HBHJH)H9r HHZZ[]HoHHE@HHBHU@ff.USQuZHHhh@HHHP H9sHkZ[]À{u&H9Pu$pi@H߃4H;t@t1H9piv@1@II)Ifo*f:aHcHv{HHf:araHwf:aGr&Hw f:aG rHw0f:aG0r Hf:asHDfo8*f:asHIAIbCDAWAVAUATUSHH(H/DHEx/HxL=`DLLgAT$/q uH}L+EtD *EtIU0Lh*L%EU8LIIII;ELeL9e uL#ID$AD$hID$8HD$~L$flA $AD$iIt$ H3*DA\A?MT$ L9LhA Ҕ At$A"E1$D ̐=IIl$E\%D9uE%*EA=я7Lc@H ML$It$H)L)DmAL)L9M͉Ml$HroIQI*LHH)I)MDI)HHMDHHAEsE{MKH$dH3%(Hĸ[]A\A]A^A_èqHtA:A9tETfET렀{AD$< I߀UE1IE1K*J*IM9rIA<$_}H@LLT$L$L$LT$ E $L=OCDOHC@LH;L)HPL@DmL'AI)M9(AIHLLhLB"EsE{IS^E*E)A\A\8IH@LLT$L$_L$LT$iȎE\A=7AUEATIUSHqPALHLBDkkHCZ[]A\A]HAWAVAUATUHSHHHDLgII)LHHM͗Mt"sHKH3HH[]A\A]A^A_HL9_u艭HHp[HVHHfHtgUSHHHHt@H+H{Ht/H]H}HtH+H{ѰHt HH[]fff.@GH]*H uHw~uGfSHVHH5J]*IHHDA;HHDYHIH2HKHHH3NTH)H)NTIMIIr%IH2AMKIH1AM9HHAH[@Eu;DXAALFE1CJ trBI@AuHߋHHpD@LDALH[Au4MvDDAaFLfFLHHPH B|B|HH4HpH[MIthItVItDIt2It ItLRALQJ<J<IN N IJ4J4INNIJ<J<IN N IM9J4J4NTNTJ|J|NLNLJt Jt NT(NT(J|0J|0NL8NL8I@M9<'DAVAUATIUHSH WdH%(HD$1HZ*HHHЋ0u{IL$yL)tP1Lt$fIt)LLU(E L;U0OMZHL](E IL$QH9wHD$dH3%(uxH []A\A]A^ÅuI@@iLhAuH}(H;}0H_H](@7IAut؃uWHH}xAWAVAUAATUSHHG Ds^AfHHAGD9uftYHpH;N8F+ HrAAJH7DAJzAxE!AzDH @HELFhMkMI{E HxAvHEAE9D9V8JD+ AEHrAAJDZAxH0A!DXAzDH @rff.9USʁ9RH;W8HcGLDG HHL; ^D9uxt%@[]fDAD9P vDxu9&+HHҋ nH fA0AIG9HFDGD)w݉wHI1Hu1댉HkHWh 1AHcw(L_DO$Hk(ILD9w`D9PVDNE1E9vC,Hk(E9vDEAMcDO(Ik(LsAA1QAH_hIk,3AAD9D;W8_A6HcGLDG HHLD;rnA9xޑA1ATIUHS9u*HHtxtMtI$[]A\ËX ։HkHWhfHWhHvH HADHWhHvH ‹%9t}DG$EEHHOMcK;4s\PwT;w8FLc_LDG LIMA;3DRE9u|AK!)H H II L DLGhH@MIB=Pw;G8BLc_LDG LIMA;erA9tA;C sRAK!)4H H AA)AD AEIC;r2IcAfDD)փB AIC;rHcD)уA HA;1sADW(HMcMk(IA;rEDA;C:EBE1E9rXfDDQE9vIC L B9wD9v5FAEIk(;2s4ADHcO(HWLk(IIA;sDLcщO(Mk(ID믉WHMA1f.%9}O$tiqL_LcOOA;s^vrƁ9ug;G8HcWLD_ HHL;mDQE9J!Ãv=vLGhH@IpDÉLOhHkE1DށA99w8ryHcWLD_ HHL92DAE9t;r dD)ʃvE AEIC;4ICEBډOHI .LcO(LWIk(ML;2r'E;rAIE1 EAA9s3BAAOC;4rD9vF ADLk(C;4sĉʉW(HcHk(LDA12%9uH;w8HkHWh 9O8AWAVIAUATIUSH(H@HXhH EN0IHDhIDHAAA@1FfAGE EoHО{jAgAL8xH@@@ǝEWIv8A_EJLFHFOILIL)M I9n AWK4RoEIHmHhD$E1E1D$D$Hx%& MV8AGIMZDHIRK IHL)H9H4@EOIAfDEHHHPLL 5AEIv8I@AH^LhhHIMAAOI7HHIIv8AOEoLFHFA_EUORL)LIML9AWKLmoMIHmHh~Iv8EZE1EIn8LUAgAWMWtfAbM@LkMkhMLAՃ|$EOIwHIkIGAFAGtBAIDPHHHfaHWHQ2EfAt$?@d@REt$M,$M|$H=ALAEt$A\$AAfEET$fA?D fA\$H([]A\A]A^A_II9AHvLkGLAGIM0IDXA5t'ArAWA_4fHLHAAtAQA_@PPAWDHHH+feLkLmEHLHMfA`I{IxHAAD$AfAAA@9Il$UfA;WܓuA2w@ʓ19gAEGD9EE1D9mv%DIwHkHH}<vAAt$?AT$fAT$H5L轐H5L覐H5L菐AGP~h@2DPAÕALXD LXfhoPAWA&@ljA鉔5uML9@|A"ILmLHNO9\o2AT$fAIv8L=Iv8AOE0ILLH1AAFǖAWLxxݗIv8LȋIV8EoA_LBAUE1ɺLIv8DL$蕋IF8EGDL$HPAx鎒ff.AWAVAUATUSHH(DdH%(HD$1Ll$LI|$uWH觛{HŋDHA5DHHL$dH3 %(H([]A\A]A^A_@AT$0ID$I;D$!H(HIt$(H~tH~HH~ID$E{DMPAOF@HuD^A?A0E&Ff u2LMtAx0Ix(HuDMHD{UHH{vmHHhH@Sf@I|$(tj*H0{.HWH?]Hl$M H=AWAVIAUATU1SHH8DdH%(HD$(1HD$ HD$LI}H{Iċ(DHA5MA.J;A.DHL$(dH3 %(LH8[]A\A]A^A_AU0IuI;u;L&HaIM(HyHy/HHyIuAD$?{EL$%AOIt$N?t(MtA.A,$AD$uFf u1HHt0LO(MuE$HD{u&LHb{/&HL`I@Sf@1I}(t*H,{LD@M TLd$ M,A}0MU(I:aIBPT$1Au0ߕ uIMMM(HyI}HIAxSxHT$t$HHHD$臒t HD$@uA}0_cHHD$QE1E1IPjL$ LHT$0Ht$(LT$ **HT$ Mm(AHL$(HLBIuv*ZY{HL`I@Sf@gHoAT$At$AoD$IĀ@pfP@髓H> H=魔AUATUHSHHBf@IHw8ED$H~LNNI)M9EX@fE\$EJ KA? fCHD9r)ALk1HHH]LmfD[H[]A\A]D DAT$HHDLc1III[McfSAWAVIAUATUSHH$$Ht$8dH%(H$1GVƇƇfff#HvHt$0F]HDŽ$LL$8 AQAAAf$A?E fEy~MMHl$0Mf}$L\$0AC AA[McH,HHl$n|HLH$_I~(Ht$8ً$HIŅZL}HMLUA$MHI)IM9ML$DM MLL$0ߠ1LIrHt$0HMHMgL}MMT$AT$I)IL9}H<$DLMLD$ t$ѾLLT$0 HL$ LT$0HMMOMHLMuLMD$0AT$0H)HL9M1H$AJHEH{(HpHW*HHWHsAGA~Aw@O@5IwN? 5AA/A E@tEeMU @IMFPLd$@L9pL{(Mtu{0H{ I/tIHtrLrHC(HjLKMtAy0Iq(H9tMfeI9u H{H{ HtL[HMIrT$XAr $EmIBD)$L9d$~E<$D$H,E HKmHLI=~L$PI~(L@$IE $$Ht$8L$HD$ LL$0H$AqAAIQLv$ID$@F\D$H9T$IƄ$HDŽ$DŽ$$HDŽ$H$@|$@kE@PoAIl$HI+t$HI9l$)MȑAO,MH|$ H4$AEH]HHIl$$H9\$bI\$$HI+\$H!H$H$tIH(Hu68kMf@H@ H@0LHHI~$I~d$8E0 $L<$Le )L$$$)$$#kfo,$fot$Lx(HE(uM|$M+|$ID=Lz*D$EL$MjI}Ht 9oIEI} Ht #oIE I}(Ht oIE($wI}8Ht nIE8I}PHt nIEPI}XHt nIEX$'I}hHt nIEhIHtnIDžIHtdnIDž$IHt:nIDžIHtnIDžIHtnIDž$tmD$IAIk0I=H}Ht mHEH}Ht mHEH} Ht mHE H0H9uH$SHt$8Ff$fDDKCEQORIL$ HT$0H9Z KAsMk$E-M H$I{(H|$PNA~M LDD$XE1fD@HDD$X@SHXAmML$MM+T$IM;L$M@EKHH|$ H4$DD$hHD$`LL$XYHL$XHT$`D$H)HiIl$EHDŽ$4$DŽ$DDD$ht$X$IMM$dA A EIHt$PMHI+|$M}HI;l$MAO4MH|$ Ht}L\$xLT$pLL$hDD$`jDD$`LL$h$LT$pAHEL}L\$xID$tu_IHD$P;\$XtZ$H$郊@AL}D$HEID$EtAuIEtHD$P;\$XuDMLMECABEudH$Il$|HAH)HHI9D$~MAOML$A2HLXID$H$D$X$HH9\$@H$U@AUmH9.ifl$@E 1D$@IE$A}DD;D$EhFf  Au2MMtAy0Iy(HuDeIEA~]HLD\$PDT$ D\$PDT$ A~,#LDT$PD\$ SD\$ DT$PHhH@Sf@8I|$(txs*LD\$PDT$ A~DT$ D\$PIAHDŽ$A{A A~2C(H$ID$DŽ$Il$}HEH)HHI9D$Z|M`~AOM$$ET$XH$HHHID$dI9D$hH$H$HSLuGf&HD$pE1xAAG Ff  Au0IHt0LG(MuEIEA~}LLA~'LִSLxI@Sf@3EkD$M+EA}M IC HD$PIT$I|$HH)Hk H9~LRHjH$Az}$L$L9$DŽ$A~D$E<$Il$Dω|$X A?Ld$8MD fAD$MMM[zH{(tdp*L A~MAEkD$M+EN~MI{ H|$PDŽ$A~~Ht$0HDŽ$H;^KH$;LDD$X4$DD$X@SHHXf@A ML$ULI+D$HM;L$yMwIHwH|$ Ht(LL$`DD$XHD$hnDD$XLL$`HD$h$I)IiIl$<$׉|$X(IHDŽ$H<$E1DLMtAAM'IA9tMIA$I)IM9v1xL}RH?^HDŽ$DŽ$BHDŽ$DŽ$A~ueDl$PD,$aM@UEkIkD$EuxH4Mk(Ll$PH$IDŽ$cD $DL$XAw{1H$M}A|$0I|$(Q}H?$HOAD$ D$E1H$LELt$PALDU0A({EAuL]Hu(I[H]IHF{SHT$xt$ HH|$PptCuDID$A|$0Lt$PH$v$k]LHD$PYnE1APHE1jL$0H$Ht$`HD$01HT$0MT$(AHL$`LI2LB}AYAZD$D$A~MkEvM"ISHT$PDŽ$DŽ$I},MN@MyM+yItIqM^@Ld$XE1H$"L~D$ L\$`l$@DA9mIUAJKSA<y@E{EAĄHįAIv@ILNM)M9MWL9VELHL迯Iǀ{=~H$D$ 0l$@Ld$XD$ nzA"M^@I_IWHLI+CISH)H$L<$,$D @>DxHXf@IEA~HDŽ$fL$HJz{0LK(3zI9MQAJL$`E1ۉl$xHLۋu0g}K}uH]HU(H{H}HHB{SyHT$pt$`HLvmtCuHl$x{0{QZLHD$x?kE1E1IPjL$pLH$H$LT$pHT$pL[(AH$LLBI3\XZA~H$HHDBA IL\$`AsHA9o|AHT$pzC|@5$vuMAƆABxMZACwMAM艌$$Ht$8LoMtAEbHxW1LhpI@SII@%pLd$8AFAML$D$hAyLL$`fDLIiiMk0HxHH$1|$hILH|$pKD$XHF\HD$PNHD$PzLDT$PD\$ 迪MUoUD\$ HŀPDT$PfHPML9ky$Eh@^HD$PL:A_AwEowIǀ@pfXDpE1HDŽ$H<$xLSL$L+~Ht$`LLLD$x\Iv@LD$xL~=IHKsLD$8A@f$f EyHx1LPp@StWI@toL{hMnAAnArAFuNAƆ1`,$_AEHxIwIIMM9toHDd$hAI(qnn^u]srOuLLfLHIH@HH$H<$E1)A yEIIL9xF A"tA\uA\I4yyD$t$I D\$ H褘D\$ IG sHZ> H=C3pff.@SDFA9:[@AUATUSARH_IL+WIH;_HIHt(DL$MtMtt$0DL@A$HCL+HEZ[]A\A]fAWIAVIAUMATEUHSH(HH $HHHu/8MTI HHx1HSHHIHl$~D$Ls H,$C0$)$Sfo $KtHhHC(LkHsH([]A\A]A^A_Hx0Hh(SHmJfSHHHHu+8SH3 HHx1HrHHHH[ff.AUHGPATUSHHH9+Lk(IMtc{0 H{ ImtI}HtoWLgWHC(HtiHKHty0HQ(uOH9*tI$feH9tOH{ HtH{I$HHH[]A\A]V@H9uI$ufDH{<AWAVIAUATE1USHH8DdH%(HD$(1HD$ HD$LI}Hg{HD DHA5Mt&EE&ҀDHHL$(dH3 %(H8[]A\A]A^A_fAU0IuI;uYH.HIM(HyHyD'HHyIuEV{DM+AOA5!HuN? EFf u1HHt0LO(MuDEHD{uI~DHHt.{RIHE1@SfDXHhHMEuDeE& 2E&XI}(t^_*H{HM !Hl$ M\~A}0MU(7~I:"IBPT$1Au0~[~uIMMM(HyI}HIAxS~HT$t$HHHD$Obt HD$@uA}0~+OHHD$`E1E1QHjL$ HT$0Ht$(HD$ HT$ Mm(HHL$(AIuLBA^_{YKUHSUuoEHŀ@pfP@>}H> H=|fAWAVIAUIATUHSH8HqHkCA}\>HDkCEUC\HDkCEeC\#HDkCAUA\HDkCAEA\HtrkCAu\3Ht`kCEMB\HtMDkCE]C\H t9DkCAU Me A\H t!MD-kCIA\$\M9ufDE~pMNXl$AAAA!DM$HM`IFA;\$ u_A;l$|$I<$HLL$(LL$DD$UDD$|$LL$L$(!H8L[]A\A]A^A_D|$AEIMAMMAAA!ADEAAAE!DGHIHHbD9{ AGE!DIHHRH-D9{ nGAE!DIHHHD9{ 9D$11LHT$AV`INXH|$IH9D$H}A\$ I^hAD$H@H@ Ht"EMD@tAT-fT(f(AntE~pI$AntC9QCHD$LHLHHHHEH)HH9tHH$L)JL뷁u>LD$MHMIIILEL)IL9tHH$H)HL<At L)JL Lt$LHLIHHL H)HH9tHH$%t H)HLHt$MHMHIIH@L)IL9tHH$At L)JLLd$LHMIH%ILH)HH9tHH$At L)JL4HT$MHMHIIHL)HH9tHH$At L)JLMHLT$MIIIL)HH9tHH$At L)JL$H|$LHIHL)HHXIL9tHH$t H)HLLD$ILxD4E& LH;4 H(ErL]H=H*L@H LEAL(I{AI|$HxIxErIAJI|$HxI{IxAJIt~ARI|$HxI{IxARItXAr I|$ Hx I{ Ix Ar It2AKK< JHPt4DLHPDžLHDžPDHH`LcLLPMcHcHH`MLLpHE9,*LpL+L`L8LHc4LH~9qH8L`LL+HuO MDLEALgEHDžELEPE1Dž0HDžhLAfH;] L{<2Ic L>f.D{CAAHCHEH9E9S9I[}L)HT[D)H9M9H]H}DAt$J ILJAL$ITK4AT$ItIVL9 H4ItH4AL$IItAt$AL$ITIVL9H4HE1/H LLL**H L L<A/1L98LY+HLA8 .L`H}H98+L8 IEHIL9MtI0A8qHuHLIEC;])DmB H4HHMHHHIIL)HH9t6HH$IEsAA:t H)HL4Ll$HHILD)H9;]dLMMD J LIHHHHI)L9HH$L98"HeLAC8Q$&LE<$<e'H84LLHuLLPAL5:*H+`I_L)M_ LH9DA;H(LEI9LGM9vwL}J4L3KL90&HUJL9&L9AH;pAEtH+`A&H+`A3IsH(HAHH LcL[AAAHD9wLLMH+L9tL`L+LP+P<t H)HL LL$HMILHLAE)I9rMMIb;]&ALMf/"&HLPL`LHECD{AHCHHHQH9Uv9w@"HQH;Us9tIcHEHHUH;MD9A_Hx8yA t A;  &Hu##L)A'%* *HEHuAWAVAUATUSH8dH%(HD$(1HHHD$H9.IHL|$ IH ԲHU-HpHHt$xDpHD$D-LcND0A8,DHDPAEMcN0L9g-8-HpHt$ 8wDJcH>1HL$(dH3 %(ucH8[]A\A]A^A_Lt$DpLLLL$OLL$Lt$AуH ۱u ǃ Au-1,H|$LH#H ,,3+f.ATUSHHdH%(HD$1HHxH<$8wMHH DLcI>AD`HHNDA8@u Ń A8uZ1H\$dH3%(uVH[]A\LHLXL $DPpL$AAuH<$D`@ADHLH$L $L +xhHH$xHcHH$HDu\@AWHIAVHI AUATUSHH׋ DRDzoHT$R H9H4L$T$؉oDGH9HHLL@LL$fDDl$D3DD\${D1Dks D1GxjDK|$D!B/Vt$F=p $D1Fν{l$DDL$|$D!‰E|D1ʉD1 A̋KA!1֍*ƇG{ E1EA|$AAE!A1ED1AA D\$ED!1DDD1DkD!‰D1F!F0D1ؘi{, A‰|$A!1E1GFEDc$AAADDd$D!1ƉDD1DC( DDD$!1D17\!D1G[DC4ʉ 1!1DEq1H@!1k D"k1!1ЉD1DcA Cy!1ʉD1DK !E@@1A1!I1!1|$ ΍b%1!Љ1|$1!1DDQZ^& A6Ƕ1!1DD\$1!1A]/։D\$ 1!1ASDE 1!ʉ1|$ 1!1DD7֋|$1!1DD! A71!Љ1DD\$1!1A D\$ 1!A3ZE11A|$A!A1AA㩉A AD1!1DD1!A ogD1 1D!FL*1D\$D\$Ή1!AB9D\$1|$ 1AqD\$11A3"amD\$ 1A< 81Ɖ11A D꾤D\$ 1AK1A5`K1A|$A1AӉpA 1A~(AD1DD1DG'11Ɖ 11|$0ԉ11DA A1AӋT$A2AËT$1D1ލ 9ىD1ڍ D1D111ED")C|A A1A *CAËD$A0eVĉAˉ1G#DD1Dd$ D ‰D1E9DAA ֍Y[eA1ƉAЋ|$A AD 1DDAҋD$AԋT$DA E1F7 |$EAA AE A1A썬0}DAEE DE1F*]EA ED DG,D1F'O~oAD D1D\$D E3CD\$A A1EDd$AAD DC4~S1ANDA D D1Dt$DA.5:A E3*A1AA AAE EA1Aԋt$AABӆED D1EA DA E1EAAE A1AA EDL$EEl$H9\$fnT$fn\$D|$fnD$H\$DT$fnd$fbfbfofl []A\A]A^A_f.@w%HO1tkCHDQu@ LҵIcL>@ODWָy7D_? )AFy7AAEA)E;GaD1ƉA))AD1щA)) AD1ʉA)) AD1߉A))D1A))AA1DD)D)1A)A)A D1A)D1ùy7AWOD)D)A‰ D1))AɉD1))AӉ D1))A‰ D1))AɉD1))AӉD1A))AD1A)A )A H D1A)AD1A _AA LtOcM>A๹y7DO ADD_ADDWADDGADwDODD_ADDWADDGAD?4A))A D1A))AD1A))A D1))A D1))1))щ1A))AAA1DE)D) D1)1ùy7&y7y7`y7w y7y7y7y7y7y7y7AA әWfH=D**AVAUATUHSH=ѵIHH=ŵoIHH=WIHH=L%x#1LHHHY{LHADKB/H)*BL-)*HLHIMcLcIK| hLHHN#J|#HHccXXXXXXACIgDHlu H[]A\A]A^ 鏠餠ff.fH=(*UH=kSQHHBH=]HHH=@HHH=H-k"uPH1HHHY{]HHADKB/H/(*BH#(*Z[]H(*þH=H-!tH=߳H-س!tH=ȳH-!HHDJH!5H!H=' Hd!H=f.@USHH(H$Ht$~D$$)$ fo $fH(H@H@ HP(@0P8H@H@PPXH@h@pH@xHHǀH([]fDAWIIAVAUMATUSHHXHXdH%(HD$H1L$HàH{ DcEAA MCMS,AHA@~HEHAPE1HL$HQLRLjjPH0C0H{8ps0HcHWHcS0HC8l1HL$HdH3 %(HX[]A\A]A^A_AAA@ CLLD$ LL$LL\$HLT$AWLT$L\$ALL$LD$ M{,HD$@@VSSQELAPLD$HAPE1R|$(LWHAVPH0Dc0H{8El$Dk0IcHVHC8Hc[0l1@@{,uiLLD$ L\$L΃LT$HAWLD$ D$HLT$L\$)D$(|^Ylff.fAWIIAVAUATUSHHXHXLL$L$L$dH%(HD$H1HPH{ D{E AA1H|$VCEAEjEt2H|$LL$(LD$ L\$LT$LL$(LD$ L\$LT$MDk,AL@@AfKRLHAQLL$HAQEQLAUAVAT$AH0!D{0H{8AWS0HcHTHC8Hc[0Dd1HL$HdH3 %(HX[]A\A]A^A_LL$(LD$ L\$LT$HT$H{謢LT$L\$HILD$ LL$(.;H9D$?ALs Lt$Dc(E1HLL$(LD$ Ht$L\$HLT$PLT$L\$ALD$ LL$(ALL$A;L\$DHHD$8EEtHHDHUExAtLDHAWExAtLDHAVEueHD$8u AHt$H{11LL$(LD$ L\$LT$R9DLT$AL\$LD$ HD$LL$(OH|$H-%AAHl$8E1E%HAHD$8BLHt$@HAV(LT$L\$LD$ LL$(xT$@Dt$DSLL$LL$H5JTHt$8A EAE|L-ALl$8A:1HT$8LHLD$(L\$ LT$LL$ LHs HA$LL$LT$AL\$ LD$({(!HC LL$(LD$ HL$HT$HLT$L\$LD$ LL$(t HCXqHHT$8LL$(Ht$@HLD$ L\$LT$AT$(LT$L\$LD$ LL$(x|$@Dl$DL{,LL$NLT$LR(L\$8A*@@{,HLL$( LLD$ L\$HLT$PLL$(AxLLT$L\$LD$ !LL$Ht$H='DH|$8DYLGALD$8HD$tE1CpH{xLL$ LD$L\$CpHH4LT$OLHCx5PLT$L\$LD$LL$ HcKpHSxHDLL$L%QLL$Ld$8A H{ LL$(LD$ L\$LT$pLL$(LD$ C(L\$LT$CpH{xLL$ LD$L\$CpHH4LT$NLT$L\$LD$LL$ HCxL?AWAVAUATLcUHSHH8Hcw0dH%(HD$(1H@;wPt&H1NHC@DkPD;k0|NHcs0A9vIHs@IRD>D}H|$(dH3<%(OH8[]A\A]A^A_HHKHIcLP HLC@LK8L|$ A4IWME1HLt$$AVAAXAY EUAD;S0HIcHA HKHH H{@LC8DT$ MD\$HA4HARE1AVA[Zt$ &;s0D\$}mAMcILHKHIA HHS@LS8D\$ E1t$MC4*LWHAVAXAYD\$ t$DHكI;s0|sPEu1,DSPHcs0dHcs0[鍙AWAVAUATUSHG09GPtmt$HHcH@HIHT$LHC@tHcs0H{HHqLHCHHckPAE1IHD9k0DkPHD[]A\A]A^A_AHHKHHB HtH HS@Hs84.HWHAVLL$DD$AXAYEHAHfUSHH(wdH%(HD$1w,H`HH{hHH{@S(H{8 H{@ H{H CpEHHq@HHHD$dH3%(uH(H[]P kf.H 5)pAVSHXH9)HT$D$HH|$HL$8LD$(DL$ HD$ D$LT$0t$4L$LʝÅAt9HD$ T$ H)8|$p|$xHX[A^Ð\$ |$put|$xD$E HËD$0H|$(Lt$L$4Ht$8LHt$ HH~L|$pK Y|$p*'|$xu^$l |$0HbH|$(m鄜|$x 鰜|$p v|$x ͛|$x {閛<H|$ LHΣHfAUIATIUSHH H޿Hv H5H] H?LH? LH; H5mH?  LH? LH H5H? H? zHP IhLH H5SH? Hxu  fDAVAUMATIUSHHdH%(H$1L$EH1Lś1H$dH3 %(uHĠ[]A\A]A^ f.Hc@AVAUATIUSH/HHHuLSAƅ}LmHEMtjIuLSt?x6IMHt4EHqLiIuHMLAHiLEH I}uiEMuImLuL+DHHtLkH H8I9u"L9t1[]A\A]A^DHtIYLAՅuHEy+IMLILiMMHMLQHiLUH H+~IMHyLiI}1yHQLiIUM]ImL]L+IfAWAVIAUATIUSHHH/H!HuLSADžtxLmLHmMtjIuLStCx6IEHt8E{HHLhIMHEHxHhH}HI}ESM]ImL]L+L;MLI?SAHHt%Eu HkHLpH[]A\A]A^A_L$$~$ L4$Hs0$)$S fo $HHtSEHJHPHHHBHL$$~$ L4$Hs0$)$S fo$HHu:f`EyDIEL@LhMEHELHHhLMHH+tLbHPL`HBw~IEHpLhIuyHPLhIUMUImLUL+f1H9Bff.19Lf.fSHtH~ Ht[ÿm Hƙ[ęff.fUSHHtHHtH!Ht H[]þHu{這1I^HHPTLKH OKH=()H=)H)H9tH)Ht H=q)H5j)H)HHH?HHtH)HtfD=})u+UH=b)Ht H=/' dU)]wfHG@5))Ðff.ATIUSH6H5)H=)HKLCL[]A\1fRF+AH=Z)1ӰH=L)H=HJqHtH5ZKHtH54%HtH5φ HtH5 1? H=)H)L11H OH=()X8= *H5I1tff.SH<)HI'H()[ff.S:1ҾH=)HH)BHJH\[Ðff.UH=$)SH1RL1H 7H!)H+)H w H=)9H)1HHCOLLECT_H2BGCC=H )H)LA HL)L)HHH9vHH=)8H=)HHL)H5z)II9u )L)H-m)H=v)HG)OIHM!H)LH)H9LGL3)L$)X[] ff.=)tmff.H)SH*:!H)H+)HwH=)7HV)H=)H5G1HHH)L )LCLw)M)HHL9vHH=E)p7H)HH=G)HH53)H4)H9u `)H9)L")H=+)L)LHLI!L)LL)H9MGL)L)=u)tH5FH=)Ha)H[HM)ff.S1ɺH5JH= )uHUHL11H H=;)Hl)5HH)H+9)HUH()fo1H54)BPER=H )HH)LAHL)L)HHH95UHH=)H5)H)H9UL)H)H=)L)NIH[M!L)LL)H9LGLu)Lf)QATUHSt;HW11f.< $U< UHBu߅UH[]A\Ðff.ATUSz*H-K*HH-S*H=7*=&*z&*='*=*$=*=)=o)=*[]A\HQ)L%PFHuL%N)HCH=IDLH1H111H5FH=)kH=#DHHH11H5EH=1)jH=CImLH1LH=D)1_=v)/L%*H=C+H HLH1@H=CH=}OH1#H-)H=OHHu=*H5q) H=`)x=z*t"H5A) H=0)kHH=N1hH1H57H=B1y5He)8u*=J*H5KN1lH=U)Ht.H=)Ht+1H=/)HuH=/1lH=&DH5)HH)Ht0H=B1H=)Hu 1GsHbaL%)Mu/1ɺHH=#)HuH*H&H5HuH1LH)H륹HH=)0HHHEqff.ATUSHH?mH{dH{+S[]A\@AW1E1AVAUATUSHHL%F)A$]SL uTSH< u1.L5)LKL(SSIM)EMt D9TLkMEA;SESA!IEA< tO<;t`SIHtLH)]tLD+A;SE'St*HHu IwLH)]tA!u=;@ S@;t@RA!SHA|$:SH5)@ f.SmHH5AHH5DH4mH5HtHH5DHthH5DH|m)H@HE[w)H@[HD^)H@A[ID1?)}l[Ðff.S)u |u [û=)t)AWAVAUATUSHx.H|$HL?Ht$PHT$XD$D(w UD$<1E1L|$DML`E1HLI_PML$$HL$(HAAD$@LDL$8IuLGHEL}H=0JH=H=\ H=H=A?AED\$0 LLL$hDD$`YDD$`LL$hLeD\$0 HcAtHT$0Nv@cuH|$0A|?. EgHT$0H=|GItHHt$`@@@n Ht$`HH=!€O  L\$0H=!GHKTHAAEE Ht$0H=FM|7LAAEEg HH=FHAAEEH=FHHAAEEtgH=FHHAAEEtGHH=yFH€DEt)LH=[FAAAEDIHPM9@Dd$0l$0E1ADT$8Ll$Dt$`L$$AGDD$@G4KfDUHAWAVAUATL%4SHHdH%(HE1D A@t+A$t%HudH34%(HHe[A\A]A^A_]øtL@L,HcH/uHHHHHH)H9tHH$LT$HsDILCA@L1H5_1 HIQIHL5)LVMt5L1L1b HI7LH)HL4n<3R=)/H=' X%)fD=)ATUSHH5)IH=)HHk({$H|)Hk(LH^)Hk(HH7HX)[]A\ff.5)@H-)@R=)HcHk(H)pXff.HcHk(H)@f.Hcǃ<uQ=)t4Xf.LH 1ҾH=) ff.ATUHSH-H=e)9H5HIHNHH(H}HHEHDžHH)HLLHHH芄)D )Hǃ ǃ| D []A\%)ff.AWIAVAUATEUSHH:LRDD$HL$L$L$L$DBHdH%(HD$x1Hz@1HHӁaO7t tzL:%HAUHEHAVDD$XLL$)XZHL$xdH3 %()HĈ[]A\A]A^A_Á`}1tilvscFAu^A E u1E@A8 A uE1EAE AuEA uE AuEAuE1EAE E#FfrsnP7C7^~YV~.$)jٰ~ODA~Yr.DUahDO'ͮo陭X®FЮj̯kMMEA$8dpdD"J4LD$`Ht$LLLD$MḬLMIHl$M~FPg鵱n`ܫLO7=ר~:XY$o(ڨ4~~GMh6~Y.Gc}x/[[%O~=^9+{LELLҾ1EEL,HAH1HHHHAHLTAE9~LIAz.m:IxEAE@|$~馥ǠDUSHH(AX?u ǁ;u ǁH([]HDL$HL$DL$+Ht$ÐAWAVAAUAATLbPUDSHH8Ht$DL$(D$/H=tDH=IAIPE9soI$H=vH=NH=[uUI|$?;=ܯHǃǃE1Dl$(Lt$pL Ld$xH\$A1D@1L@DD$t$ |$$RHH ATUAVAUAWDL$PDD$TL$HHt$8H|$@RH0;uH\$|$/DHD$AHHdo&L|$LMLLqMLLLƿqHL$LLLLLƿHt$LELGLELUE1䃻H)AE1ɃDAE1҃IDL$AELI At7PEDH$U$D\$HASATDL$@Ht$8H0H8[]A\A]A^A_ÿoHT$A HL$wHL$HT$oL|$LMDLALNqMLANoAWIAVAUATUSASEDt$@\$HLd$Pl$XLl$`HRt Et E@t EA L=SIcL>DuKEuFIJLl$`AD$XLd$Pl$HD$@EBAZ[]A\A]A^A_AEuIzuyLk`L5a7'C|@xfAzALl$`AD$X1Ld$PE‰l$HD$@뗅A맃A랅AAE!돃AE E{X[]A\A]A^A_H0YH=7UH]H=tUH[H=\Uff.@HI1 <.HDHфtHQ0fA AD$@A@Dt$M4MAHk`L U,'ET0fA_IwMk`H+,'IfA|$07Hk`L ,'LH}(Hu HHpտMIIk`L +'L͋E<\E1|$Ik`H5+'D>@Au-u EMk`Hp+'BDA&MMk`H=P+'JtHIk`LL4+'AD@DE1AnI1HHHDHK(LHHIDIAIHHHDHK0LHHIDIAIHLHDHs8HHIDID$1$Ed$DMk0DD$0Dt$LL[)H$LT$ DMI|$LT$ DD$0$H$DDD$ HDŽ$I|$LT$0DD$ 7LT$0H$L钾IPAHDI0IhL$pLHT$hHHHLILHLQLT$HD\$`EXLI?LD$0ALL$(ED$Ht$(LD$0D$l$`I |$pH9CLD$p1AHL$`LD+t$Ht$0HIcH)HLALLD$(5HL$Ht$hHLT$(L\$`HD$Ht$0H)I3JLt$HxjH|$H[LD$pAI L|$8LT$PHE1Dt$HT$X1M:D2Dd$ME1HD mcL&('M߹LރHkPHIPE9ACLI;gѽr'D9νAHk`Ly8xA>@uDE9EAIkPLHPD9snBLuH2A9vH@HLDh8Ex@>@uHcAH@HIcD89t*9tHk`IcD89t9tHk`IcD08A9tA9tA9ADt$EH|$8AHIkPHl$PLT$XHEAH$dH3%({HĨ[]A\A]A^A_EK4L6H>H9D$wAM飼Ll$ HHCLkLkLk AHC(HC0HC8HC@HCHB~|$|MϸLDD$0LT$ LT$ DD$0$Et$\AA;D$XwD9iM$ HMʷDŽ$HD^0AWE1AVIAUIATIUSAPDHLH3HvLu!tCAZ[]A\A]A^A_C tASHH`HT$@1LD$PILL$XLL$0Ht$8MHL$HdH%(HD$(1D$HD$pLL$ HD$1Ht+L|$HHT /|$LH>L )HML+ )L9H)Lج)HL9H )L)HT$0D$HT$ H4HLH!L)IM)I9MIGLT$pI1LT$H5})H5n)HtZHLHދ\$LHHI/w'AڃLT$ \$IHt$L^L\$LT$IRHT$ALH\$(dH3%(uH`[ff.fHQH ^tAH 1NZff.E1DHHLMt 9Pt/AE1EIIMMA9SutL1Ë@ t镽AC tA@Hk`SLAAPHI8I@IpL4"'ADHAAAƽ1A XH\$HdH3%(uHX[]A\A]A^A_UDAWL=C 'AVLcAUAATMk`USMHAD$BL$PL\$XftEHHt=AHEt MHu3Ik`ALHwH5Hc,H>D+H[]A\A]A^A_Mk`HCLHwL%AKcL>D+HtE1Ik`IMwPAGA(END3HtL1Mk`L%P)DHG|DMk0MAT$ H]MT$ HH[]A\A]A^A_A1Ik`LWALOPE@ƃ@8IL! HIk`IM_PAGAL ]LHL-" Lm1L#MuLD$%LD$I1ҾLLD$IM$HL$AzLkWARKt L6HNDnL#HULeLMAEƼL %AD! D ]DDLLD$@HLD$錼fHcH'Hk`LBfHf.AWAVIHDAUATEUSHxH|$Hl$$HDIL$L$dH%(HD$h1DHLPAUPAWD$D$H|$(aH HL$hdH3 %(uHx[]A\A]A^A_߾ff.@HcH'Hk`HABfHDAHAѻEu 1>At/Au%LAPAAt LAALcM@@ÃHyPAAu HcHH>fLcL"'SIk`LABfHxyHdYHLGMcM>AHӉHLCHCLC[Mk`H5'HFTAAAMIILJ[Ik`L L)HA|2DLk0KLHJ[HHuHHH:1HHHJ[AWAVL5!'AUATAUSDLk`HhHT$H$H$H$DL$O HD$EQ0HT$ L$HL$(dH%(HD$X1fAAAtMtىDL{=EHD$XdH3%(uHh[]A\A]A^A_^f.@u!Htw?bCHtG1AWAVAUATIUSQHHuqE1t[1I<$E1I<$IHkHHtDoAI$DxD `EuFAZD[]A\A]A^A_Ëk%)9vLE1{yHAgE1HkI9t"BoDBDNLNLIE1됉hf.DAWAVAUATUSARHz@HDzHHHAEE=o~2==F=fZ[]A\A]A^A_=Q =i=u҃u(VHt$Pjt$XAQA1APEH0u+QEE1t$PHHjt$XAVAUH0@u+REE1t$PHHjt$XAVAU^H0Pu+PEE1t$PHHjt$XAVAU*H0u+PEE1t$PHHjt$XAVAUH08u+PEE1t$P+HHjt$XAVAUH0@u+PEE1t$P/HHjt$XAVAUH0u+PEE1t$PCHHjt$XAVAUZH0u+PEE1t$PIHHjt$XAVAU&H04u,ASEE1t$PuHHjt$XAVAUH0@u,AREE1t$PxHHjt$XAVAUH0u,AQEE1t$PHHjt$XAVAUH0u,APEE1t$PHHjt$XAVAURH0uAQE麆t$PEH1jALt$XD\$XAASD$XP{H0pu2APEAHt$PLjt$XT$XRL$XQ1@H0u3WE1ɺt$PLjt$XDD$XAPt$XAVHH0u3VA1ɺt$PHjt$X|$XWDL$XLAQEH0u5QEA1t$PHLjt$XDT$XARD\$XASH0u1REA1t$PHLjt$XD$XPT$XRPH0u7PE1Et$PALjt$XL$XQt$X1VHH0u3PE1ɺt$PHjt$XDD$XAP|$XAWLH0\PA1ɺt$PHLjt$XDL$XAQDT$XEARH0Qu~"XݢhuEEE1=)AQELt$Pjt$XL$XQt$X1VHH0luF¢E1=6)AR1ɺHt$Pjt$X|$XWDL$XLAQEH0puH{E1=)APE1ɺt$PHLjt$XDT$XARD\$XASYH0tuD2E1=)APE1Ht$PLjt$XD$XPT$XR H0xuDE1=I)APELt$Pjt$XL$XQt$X1VHH0uFE1=)AP1ɺHt$Pjt$X|$XWDL$XLAQEpH0uHE1=)APE1ɺt$PHLjt$XDT$XARD\$XASH0uDОE1=\)APE1Ht$PLjt$XD$XPT$XRH0pt 1=)@ASE<Ht$PLjt$XDD$XAPL$XAQ1H0du+AP1t$Pjt$XT$XRDD$X9APAGH0FWEA\t$PLjt$XL$XQt$X1VH H0XAQ1E6t$Pjt$Xt$XV|$XHWLH0EtAREA1t$PHLjt$XD$XPT$XRzH0tP1ɺt$Pjt$X|$XWDD$XLAPA;H0Bd5V1ɺ9Ht$Pjt$XDL$XAQDT$XEARH04Q1t$Pjt$XDL$XAQDT$XEARH07f7f7fFXDFWVN/DDFTDNVDDVDD^DF VDN&DVPPDN2DDVDD^D<FxHN*DFDDNDDV%DvD@AVAUL-aATUH0Sf H@ Hf@,@6HAĉHEtLLs0Dc(HH](+fɿ H@ Hf@,HH6H߉AHEtLLs0Dc(HH]0fҿ H@ If@,P5AHEl LȈ1HkHH8I9wI$Ml$Et$([Le]A\A]A^@UHSHQ-tHH=)H},u-HW1HHHHH9uZ[]H111HK#HuH1_H=] UHSHQ-tHkHH=)l},u*HLJ1HkHHH9uZ[]Hk111"HuHg^H=\ f.@AUATUHSQLo(MeIEIIH@HxmHI9wMtWIuH~HH9wA},I}:A}-tIULH=)H0LzLm0MtTMEMHIM9wA},I}ڊA}-tIkULH=)0LH]Ht[LSMZIM9w{,H;u8胊{-tHkSHH=I)TZH߾0[]A\A]v!X[]A\A]g!]]!H; H{0HKHL9rE11LH uLm(HHyvAVAUL-q]ATUH0S`f H@ Hf@,@}2HAĉHEtLLs0Dc(HH]( fɿ H@ Hf@,H(2H߉AHEtLLs0Dc(HH]0fҿ H@ If@,P1AHEl L訄1HkHH8I9wI$Ml$Et$([Le]A\A]A^@UHSHQ-tHH=)H|},u-H71HHHHH9uZ[]H111H+HuHi[H=fYUHSHQ-tHkHH=)},u*H觃1HkHHH9uZ[]Hk111HuHZH=Xkf.@AUATUHSQLo(MeIEIIH@HxmHI9wMtWIuH~HH9wA},I}A}-tIULH=)H0LZLm0MtTMEMHIM9wA},I}躆A}-tIkULH=)0LH]Ht[LSMZIM9w{,H;u8c{-tHkSHH=))4ZH߾0[]A\A]VX[]A\A]G]=H; pH{ bHKHL9rE11LH uLm(HHyvAWAVAUATUSH(H|$H2IHH|$E1 HHD$IHIDl$AI$HD9xDLtMLGIH)HH1H)9vLHL9Gt$9wH|$DLA/9vLJ@ LJATUSHDbHH-H=w?H \HHc H>AHW@LG(I,L EM HW@LG([]A\þHG@Ho(H1H EH HG@Ho(ALK@H(I M EL LK@H{(LG(LO@EAI2M M LG(LO@sfDff.ff.1f1f1f1f1f1ffD1f1fff.1fff.1ffD1ffD1f1f1fSHHHPH=fCp[@SyH CC[ff.fUSHH(H?dH%(HD$1HD$AwHD$dH3%(uDH([]H= )HL$HT$HtH;tHcjHx}菃ff.@AVAUATUSH0dH%(HD$(1HcF8 H,()HIHEu.)AYIHL[H )]1A\H=o[A]A^A_5EH>[H4[HEED H=·)1'DHHt$(HT$0HL$8LD$@LL$Ht7)D$P)L$`)T$p)$)$)$)$)$dH%(HD$1HT$ HH$HT$$D$0HD$sHT$dH3%(uHfDSHHHT$0HL$8LD$@LL$Ht7)D$P)L$`)T$p)$)$)$)$)$dH%(HD$1HT$ HH$HT$$D$0HD$tHHHHD$dH3%(u H[SHdH%(HD$1F 4H\HHc H>xHD$dH3%(uH[x&H=a)H5>Y1规USHR8g+H{H.}H;HCHHH;}HHHX[]ff.AWAVAUATUSAP^9wDM 4HGHLcJD3uZD[]A\A]A^A_AAՉHEsXH{PHcLk MxN I A9itEqIw'HCPFd8 H{PBl?LSPGl:CXfDATIUSH`H$H$L$L$t@)$)$)$)$)$ )$0)$@)$PdH%(H$1H$H\$ H5)HT$)HH$HD$D$D$ 0рLHL$AH),H߉߁H$dH3%(u H`[]A\9}fUHSHhH$H$L$L$t@)$)$)$)$)$ )$0)$@)$PdH%(H$1H\$ H$H5Ճ)H$HT$HHD$D$D$ 0HL$HAH+HȀH$dH3%(u Hh[]&|fDHcHr!)Hff.fATIUSH`H$L$L$t@)$)$)$)$)$ )$0)$@)$PdH%(H$1H\$ H$H5)H$HT$HHD$D$D$ 0~LHL$A H)H߉H$dH3%(u H`[]A\zDATIUSH`H$L$L$t@)$)$)$)$)$ )$0)$@)$PdH%(H$1H\$ H$H5)H$HT$HHD$D$D$ 0}}LHL$AH(H߉~H$dH3%(u H`[]A\yDSGhHH`pHcHrHcSh{XHC`JKh<[ff.AUAATUSHRDghEtAHG`DghMcF$SXH{PjHcHk H HCPDl(HsPDd.H{PD/CXX[]A\A]tXVu:H=WvHt%H5WH {tw1ZHXXH=]W1@ATUS@H.[]A\@HH9WHDfDAWIAVAUATUSHHH|$ H?dH%(H$x11H |AlWNA9Lt$ L$E1AI> I>1HD$(zHLLzH$H$HD$HL$H$hHD9nI}D$H|$0L$ED;F El$E$$H$H\$8Dl$`Dd$ t$ l$`9/HT$8H$1Mo8$IHL$`M$I8HcÉŅ[ATHу t tHcA\4؃<  Hc$p AIAHDxD `EA3f.AWAVAUATUHSQHHt$DcE1%D)9wxZD[]A\A]A^A_E1tE1H}E1mH}AH4HNAHEDxD `EA눀{E1ff.AWAVAUATUSHT$dH%(H$1H?IHH=Rr)6H|$ IʼnHD$I H|$@DDd$(3H|$`1ҋl$HDt$hIGH9D$ HL$H;D$@{tH;D$`IWxHt zt$,|$LDKDT$lt$|$DL$DT$A9IAw6AwDAD|$|$1ҾIxDIoxDD$L$T$DMt$Dd$MkEQDUJDDHDhP @pDpD`H$dH3 %(uHĘ[]A\A]A^A_iAw;HL$\f.AVAAUAATUSEAE9DA9AH=Qp)DH=Bp)ILII9m][]A\A]A^ff.UH1ҾSHPHHMBpHDrHZ[]ff.@H)HiGNH)HeÐG 9uÃUHSStHHw0H: K] 5H5GHcX[]Ë}HLUH1HMA{CIIIQH]HH;AY[]D Hu HmH}A[[]/ ff.SHGx1LPH9xv*EAZA9MD9r A;R} I1[9rA;R AEtLkA9LL$AIABtA;ru A;R uA[9[D9 ЃfUHSHH99$H[]Ðff.SHHHtdHH(H{xHt id{D[f.HM )ATAPUSHH_HHHkHDc(HCHCHC HC0HC8C@C@C []A\ff.@w(H&rff.AWAVAUATIUSHhH_H4$HKxdH%(H$X1HHCXH+SpHD$HHkpLChHHkpL9^LK`HH|$`L,$HLD$$MpL)D$ HHLD$0H!Lt$ILd$(M)LL$XI9LL$HHG<1E11EHkpAHkhMLImIHLT$0EFEIKHT$'M]pM9]x IMpIHAIEpA|$@9A$%uAl$I\$@<v@%%@' @ImpI9mxM]pISIUpAA;HD$IuhENEImpDL$8JE1E1E11A?@lI@q@w*t E|$WA.AL$|$WIs/׃H~H7L|$WLSpL9SxwL{pNl`MGLCpALKhL[pM9HH{xLs`I4HHH!L)HL)H9HGHspHshMM@#@+EA@R@m@>LT$(LEAzC HIUxI+UpI1LHHiH9I}pLHImpH5A)H1MUxM+UpHHLyM98I}pLHM}psI|$8HHǃH\$AD$@I\$$AD$ H$XdH3%(Hh[]A\A]A^A_Ã/\AЃLFI0HL&ID$0HVAALAVLt$ ASHt$ H aLAt$CLAt$CLD\$(DL$8DD$$L$ D\$(DL$8DD$$L$ :|$WD$WII]pI;]xzLCAMEpMMhIEpL9IM]xMU`HT$H4HD|$A/w>DAIFE>H0H1HA|$CHHQLHIFLXM^fUHSHPH:XHkHnC@C Z[]ff.@AVAUATUSHH_LH91탻8IMl$ItHt LZI$H{XHL;c`L;cxLd$~D$flChH[]A\A]A^DUHSRHGHHSH9S HKHqHs H}EALJX[]SHHHt WHC[HGG@G LuSHHS[H \fSHGHHXHSHHYH[|ff.H}(USHRHH8Hu.Hk1H}XtH1jH{AVH{X[]5VHRff.fUHSPH59)H5ETZH[H]fDAWAVAUATIUSH8dH%(HD$(1HuHHHHQLl$LHH-wL=9MuDU5HI9uLLxHD$(dH3%(uH8[]A\A]A^A_dW@SH@HHH58)H[@HGHGÐff.S1HHXH1[fDH щH5^)$_@UHSHHHT$`HL$hLD$pLL$xt@)$)$)$)$)$)$)$)$dH%(HD$H1HT$PH$ D$0HT$@D$40HD$8iTHt$0HH,$Ht$HL$*HD$HdH3%(u H[]Uff.USHPHo$HG$HHk$Z[]DSHH{CA[DtS HC[ff.S@H_H߾ [QSH51YH5 YH58H=TH=TH=8!UH=Hc6)UHJ6) XH[)Ht1H58HHRYH58HRBH= 6)H5y8Vu2H=5)H5 vVuH=|[)H5)[DS1HHdH%(HD$1HL$dH3 %(u HH[Sff.fSH4[)Hu[Hk{XH HXHH9[)uHksXH{H[HZ)Ðff.AUI1ATH5=30USPf@H@ Hf@,@H$H߉ʼnHD$L Lck(I]HZ[]A\A]HH=?Z)dH%(HD$1HH$HT$dH3%(uHRf.AWAVAUATUSH8dH%(HD$(1HAIHHIcH;k8wxH{PHOLC@IdLL9;Hkd1IH9|AHkMkLL7J;lI9MAH9~HLC0H{8HH9k8HS("Ll$ fML+sHS(Ls0I9HCH;S 9H{0HBH9(H)H{ RIH]CHH{Lp*PHS8HK@LK0LZL[8L9eHCPHt1pcw Hdv+KH1HHt!H9sL[8+Hdw 1I9vfDL\$L+{H{PL~T$LL$L|$ T$)T$iH5H;S +LzL9{0Lk0L)Lk LQHHCHIHH{(OHK8MHs@AM)LS0L;S(HyMCH{8H9v@HH+kHk0MtE<$Ht$(dH34%(LYH8[]A\A]A^A_LCPMBEHAcwHd;Hkd1HEtI9wH|$~\$Ht$H{PLT$L+sLt$ \$)\$.VLkMyMM)THHs0HS(H)HsH PIH"CHLpH{Mu^LC8HK@LK0MXL[8I9.AL9v7EpMkNL?I;)HiHHQE1EmIkLLfC0NHdE1L9VHHS(AUH5IATUSHHdH%(HD$81RIHH=sU)HfU)+HCXHH{tHt"9BHt HXH9tHH;sH9HBH{LkHH{PfLcC(HC8HuH=T)HT$ L+D$ St$ H|$1ɺ LcD$LC@ICHH|$8dH3<%(Lu+HH[]A\A]LdGu MfRfHHHHHHXBHBBBHBBHBH9uH S)Xff.fUSHQHNH{@KHC H;C(u$H,HH{HDHHk HCH{(HS HKH)H{KH{HJ_Hk(HZ[]Ðf.SHHHuH{Hu*H{PHu[fKHC݀[IIHCǐff.AWAVAUATUSH(HHI:A,11HDHI6ILLkHCKLmHH9C(C AALHIAPAH E0IH )AA)ELHI4:D>Eu'IHCK4 >u.LfH([]A\A]A^A_D9tE@AUMI D)AAED)LsE C$MM9LHLD.Ex@PH=bQ)16H=OQ)ZfDATIHc1U1H1SHA<$H1ID$9~ L H[]A\ff.SHH=P) H=P)H1ɉ[VfDUHSHQ-tHH=SO)H'},t6H111HHt.1HHHH9uZ[]þHBH4H=%H 7@AWAVIAUIH6ATULSHXHL$H|$HLL$H$dH%(HD$H1Ld$L|$H I9)~D$Ll$0$D$8LD$@H|$8IIpH9(H9(LD$0fAHt$@H)LL$0A|1 M1x(A1 L\$0Lt$@LL3Iv A;-(L]H\$HdH3%(uHX[]A\A]A^A_Gff.UHAWIHAVAUIHATISHH(dH%(HE1yEu;IH IMOEOHUdH3%(LHe[A\A]A^A_]I1LLHHN1LHHIKt0HHH)HIL9tHH$t H)HLH|$LHLEHH}GILUL]LC2/K|2ISL5("IHEI6H}~Du-LkeHn(AGIIt$IT$I7IWHELEIIuZ'0FAUATUSHH8HHdH%(HD$(1HDH(EH3H-3HDH'HHH 3HEHHIHT$HHLo$H 3HHDo $LL$LL0 D0EH/3H X3HHxL\$o$$H2LHǃH8H 3HH=Ld$HLo$H 2HL`ǃ` PHL$o$HHxxhHD$(dH3%(u H8[]A\A]qD&ff.AUHs E1A>ATUSHHLHLHLJHjH"LLH[]A\A]AWIAVMAUATILUHSH8H$pHT$H$DLL$0H\$@dH%(H$(16HH$H$D$N$Mt$N@HD$(HT$8L$H@8)Ht7A<$AEC$DH$\IL9uI M9Ht LLLH|$8L)HD$(ЄML9Lt$Ld$ IML|$HtJIDD$HL1IH$H$|L$H$HEDeM|$H$(dH3 %(H8[]A\A]A^A_Lt$Ld$ ZM9MfMt %MfAVAш$A"AYG#L2AIc4L>Ƅ$ HL$PHt!H|$8HD$(H$Є%M$MfƄ$ 빋t$`T$l|$OII I M@8|$N""MF1E1L9t$`@c%HL$XEL!I9#%HL$PHt*LT$pLT$DDD$HIILT$pH|$@=H$HT$`D\$lD$OH I M8D$N!H|$r!MfM!L11E1H E1L9A $HD Ac""IM!EAAEE Lt$Ld$ sLX;M9&A$DXA&IM_&FtM@L ' HT$XDH!H9AAD Ld$H|$@ U "=Ƅ$ Ƅ$ Ƅ$ Ƅ$Ld$A$r|$Ƅ$DT$lDL$`L$L$L$|$OD$D$HDŽ$DŽ$Ƅ$DŽ$@8|$N#MvL$M#H$AUHH$QH|$ 1L$L$E($H$H$hAXZE"HL$PHt$LH+$H|$8HD$(Є#M"L$M}#p@8t%@Rt$@'t@"u LX4Ld$<#<$[!Hl$ ff.9H wH 0HcH>oLLPohLxLOo8LHLGff.@UHSHHHyH:H;A$H HHHHHSH[]ff.fAWMcAVAUATAUSHHHiLII9u+HEH9L9x$HUHSD$/H[]A\A]A^A_H LD>HF1AIHIIH4(IL9#E1IzM9t(EDL LE!AE$IIE)LS{ff.HE1jHfAWAVIAUIATUHSHhDFdH%(HD$X1D$0HD$8DÃ81A<ȍ|Q;~#HL$0PIjHvE1H;ZYf#D\$0L|$88HL1ҹ HII IFAHLHS1II1I9vA<!Hw HM9[#MI!#Hw'AAAAQ@uAD#1!E}A.H|$8I;|$t6Ht$XdH34%(Hh[]A\A]A^A_AT$H|$@HT$D$HcD$P HMؿH D$$HF1HD$1HH1HHLM)N MLD$(DD$MH9t!E!IICt9!H M9"D\$A:H|$"A"A.AE47@IHHHH=AWIAVIAUATUSLHHIxdH%(HD$81I@HT$Ll$0IHL$(HL$Ld$ H)HL$Hl$(HH|$0HT$ Ht$MLHLAH|$(t t1"LSL+T$0LSHt$8dH34%(uHH[]A\A]A^A_N6ff.ATUSHdH%(HD$1I8D$"IHHHHT$Liu7HL$MuI L$Ajt$@rDD$F HHmH\$dH3%(u H[]A\5!ff.LHAUATUSM.bAȃwHI LH1[]A\A]AL-dL%dGTC,DAA!A9aM9A!LhLAIEEEAAaA?DL9uDQAawIwlwIw@wIw<wIw8(taM)ى H1LTTTT?aff.UHSH8dH%(HD$(1~c@t$'HD$p-HHt$'HD$H$HcH|$bH<$/1HT$(dH3%(uH8[]3f.ATIUH-(S1UHuLH#TPu[]A\@S1H1HH11HPHHyb@H H1HHHdb1@H5H1HpHLbH5y@H= 1H3bHxH5yH@L H1L@HsbH5y@_L H1LHH@ H5~y@8L}H1@HyH5WyLPLw}@LX[AWAAVIAUIATIUSAPHH1HLHHQ%"IHHH;ktH{D8{hH1LHLLHHQ!L H I;i"hM MuL K*I1LLM$L#Il$ZL[]A\A]A^A_Htg L*H1HIH3IHkCD{=gff.H@UDAHSHAQH(0HHtpH{(踁HHgZHH[]ff.f1ATAUSHH dH%(HD$1HL$ HT$cGHt$HD$Hn8HMnHC(x0!nH\LMmDD$ T$DHHH-H|$HmHD$dH3%(u H []A\/AWAVIAUIATIUHSH(HޢxSHtAS>DLnDCE1Ax(DKLSHIAIIrD[AB{DAE}L-(L9t!Mt cm1ҾHH(L[]A\A]A^A_HK9Rom@HX@HSHu AHH[fUDSAAR:Ht @@hXX[]fDUIHHHHdH%(HE1IHIIRMBIHH)IHH9tHH$Au5HT$LHHBD 1LLHEdH3%(u L)JL-ff.@UHHSHHT$0HL$8LD$@LL$Ht7)D$P)L$`)T$p)$)$)$)$)$dH%(HD$1HT$ HH$HT$$D$0HD$PjHHHH*HD$dH3%(u H[],ff.DUHHAWIAVAAUIH=ATSHdH%(HE1LH,HHHSLcIHIH)H9tHH$AuZHT$LLHHHtL)I(D)B" LDLHEdH3%(uHe[A\A]A^A_]L)JL+DAUATIUSHdH%(HD$1HHtvI@H,$?HE<twMI$@YHFhHkH(H"lHHHH$HH,$EEIm11LAAEEHD$dH3%(u1H[]A\A]HLH8kH,$IUHUc*UHAWIAVAUATISH(UdH%(HE1GHH@<kD+<5-lLE1IO8PHMkL襝p@tW@ckEMO8IkMAM+AH(L9!kMkMQoMACH@IC EufAbAE*kIW8HJDqHI $LcIAL$DqLIIILHI)LH9tHH$AuHLL$IA#H[IyH3LLAoH]dH3%(uHe[A\A]A^A_]L)JL4 )ff.fAUIATUHoSQH]HtAE1AE9Cu0D9cv DHkHIt=H$jD9ct H]HZH[]A\A]ff.fUSHRHt/HHHlHHlU?tXH1[1]Ef)l=lalH,6f.SHG(Hx0clH[|ff.USVHHX`HIl{HRl{C tEHCX[]1H%ƒUCAVAUATUHSH0dH%(HD$(1GHt$ D$ GIoH@A|$5)D$HD$ mIT$HHHmH;Su{tHDsEnHJx5IIMH[HHmH;KuE{uRLMt 1LHAЀ{mHS{zmmHD$(dH3%(uWH0[]A\A]A^DKA|$E t$ DSƅQfD]DDU!EuAD]&m mHG(x0mS1H1H9H1Ҿ[fATL%VUHSGH4Pt25nHXCuC?,nH3fK[E]A\f.@ATUHSHPHHH)HHHL LaIHHH[LP]A\ÐIHL$u.Eu)H@HLHHHH҃8uL9L9@!ff.@AWAVAUATUSHDEOH1HD$I11E11E1E1HD$HD$H`M ,LL$LL$MIMI H|$AHAEHAHHAHH`H|$7LH MH|$"H|$MHHAMTD []A\A]A^A_DDHjARAkArHEhE@1E) tMHYEHADA3wL5jEOc M>AAKu HD$IUA@%E`\ >iHGHe~@f/@l% xMJH@MuAHD$_ȃJff.WHG19²DHyA'tA"uDtDJMF8tDHHfJ>f.ATL%1HUH-(H5KSMHIAIM1H(HH5AH0MI1H8H8H5HPH$wAH 11H@HHI[]A\ROfHt$~D$II1fl#HF H~LHHNH9t H6HuIH8:tHH HDSHH8DH8EHIHpDJD[ÐAWAVAUATUSHhDdH%(HD$X1EsIHA։ՄHC8HCHsH HL $`Ań+H5 ) $HA$I<$HHk@HDGjDuE8EBE1EAE9$~(fuHsI$,ƃfA$5HSxHs(ALEGELDpjHs0HXPHSHp(1AƄ$IDŽ$H|$XdH3<%(Du@Hh[]A\A]A^A_P?E1E1A$1=t@.AWAVAUATUSHDET$ HIC`%=`=D$ HkxH}E1[IHꋻK4>L)cHIL9uڀ|$ =HSxHMMLIPLK0ARLƃHC(ZYADǃH[]A\A]A^A_H 隸L9l|$ aLCT$ 1LH o_1rAAWAVAAUEATIUHSAQDLHHt~QLHAAUE1EHA0^_HuEuNHxuuKvHu(n81҃DHHuH}(G8Z[]A\A]A^A_1fAUATUSAQ>/kHHHXPHtHHGZH[]A\A]ÃH DhjH{tHsDYH[]A\A]VH{CH+CHxI HsLHB HCHK@HHH9HYAVAAUATIHUSHI$0Hމ=HIHtHzHj[H]A\A]A^þ@ HHHI$H]HE1DuLHE(HHHuML$(MEH@EQ8LHhDPIEfDtH~8u HHF8ƇH۶H9V0uƆfF(H@E1Off.@E1 f.QHHGtH8hZHxHO(AA HHHt EAHDBjq<H+0HPHHHG*H8DAW1AVAUATUSHHH<$Ht$HI HHuH1HrL-^ H$IH@HfHuI7HA|7DEGܸHD=Lw8IIIHKt2LDL[xHM\/I/H[ H;ff.@ fUSHRHKHH]xHH@GHH@H5wX費H@HH5Z莻H@HH5ZjH@ HH5ZF H5H}HfHH@H5ZHfHH@H@HH5ZZκHX[]H@ҹ驺fSH_xHHH+HLHI LI9HLIHI!HLL)L)H9ϹHLG1LLH[Ð=)AVAAUIATIUSuWh)SH5H=oGo)|n)^ff)[]f)\fj){#e)}M)~[<DHhPH1HLHfo/\fo 7\fǃcǃXfǃpƃlfǃsƃzƃ|fǃvƃxfǃǃƃfǃƃnfǃƃfǃƃHǃHcLHVCHHLk(ƃSHǃƃfǃHfHSPH1LHHCx1HHC8rfHHǃHC@L(11H >H(BHLHH[]A\A]A^\HcH,YHkH DBDJDRDZrBJD`DgDBDJ D@DZ r D{fhDjDDR RDefD@ifDATUHSHu^PH1E1jE1HHLH HMZYH 11H@H[]A\HHHnff.UHSHQH;t1Ht,HHH tHH!kX[]ÐAUATUSR`uEp'uX[]A\A]Ƈr벀t޽L-(HMIuAUHIpp`?f  fpEEG DHM9u냀epPff.fUSHQouH5NTHj`\tWt H5TH(ht'`uzH5THH5THH5THb X[]ÍP"Hpw(H5SHt\ t됃 wH5SHqDH5SH]0պ̺h/ATUSH HL%K(L_AT$I4$HTPPx?f΃ A|$ fxt? fxED$ D@IL9vfA|$ u\tHu[]A\f.DS1.HH@HEH)[UHSHkPHHEHEHHEZ[]ÐUSHQHW8HBHJH)H91Ã=u߸A7A5@A8@uA>@@ÃAA5DIAA+A AE1ۀAÃ/@ǃ* @Ã-A>AE A1+HVA5A2@\AE ubA@@@A A1DAWAVAUATUSAPX[]A\A]A^A_H#HU!SHH5YP1HS8dHYe'kpHCXZ[]f.AWAAVIAUAATUSHHDg8A_OxAątA!AADS$D9S ?DAHk(HkDS$EMt A>D]DeDEDS LuADSfEDc8DcDSL{ D9HH+ADmMt4A>u.AL5b%Muk01b}}WApALc}AuIL;MAOEG E+MwAE_EGHkHH{H<$HAHSPC<ADD$ HD\$H;HƉCHDC L$ A HDL$IJ,DL$L $1HL$ AA+ITD\$DD$ EC0SHkHHs L{$HSPH4$AHtsEDD$ D\$Ik(ҿ(1H4$HH{C Hk(DC$A(L$ HCDL$Ik(H,(DAkk L5O`W@HHdH%(HD$1HwHHGHG$G,GPGhHGpfGx$D$ HD$dH3%(uH0HcH,HL @UHSHH8dH%(HD$(1~4u-v H藧o$o\$s0S8[HC4oC8oKHEMHL$(dH3 %(HuH8[]@AUATLgXU1SHR;kXyH{x:H{(X[]A\A]*f.Ht1ff.AVAUATIUHSH dH%(HD$1HD$HD$9DH~SHD$Htxt$HL$dH3 %(u H []A\A]A^Ll$HLWv HL$ytLt$Ht$Ht9~u3v H|$t#LHLHƉMWMdff.AVAUATUSHq_ fIIHLcIFLHHEHxHtL4uыU 9t&IHMIL1Au[]A\A]A^Ëu8ff.AUAATIUSHdH%(HD$1H$9HtA9\$8E@ŃADHLVH4$E~DAAE9NAøE)DڃVD!AD$ HHI$DFH9@NAD)D9v'DLGAA9D$8rLPH;$ADH|$dH3<%(u H[]A\A]fAN+F=`wND!Ћw$AD99G8ff.SHH dH%(HD$19WHcHH| DGuC4HD$dH3%(uH [Mff.fUH1H5PSd1RHPzHEXH}XHkHuh9]`_ff.HdH%(HD$1H$9*HZH$HBHL$dH3 %(uH{ff.HdH%(HD$1H$9HYH$J+BHL$dH3 %(uH@U%S9HkHWh %9 H9G8s\HoNAAD9DLPE)EGDD%D99M8D)ˍ\E9[]HcH2HD fDHcP LLDATIUHSH XHtE9~*I4$HcH4[]A\EXHE HEHH4{1HE HfHHxt@RP0|HH(HhHRHiXt$LLILM;AtMQMt?HHHHH;BuHJHtLAHLfUHSHQ?HJHH3EoF@H;DGtAfD@HX[]AUHAWAAVAUIATISHH8H:dH%(HE1@LA@HADHHHHHH)H9tHH$%Lt$IuHILq@IMHHEyA|$StLHD@H L)LHHcH>HH|LMH M9$IEHAHMdH3 %(DuHe[A\A]A^A_]H)HL-6A|$V\DHE1*B "b\Y KIHI9ufgfgÐAWAVAUATIUSH^ڃ?)IFInAk^ EDkA$ D]E1E9vXIkH]{PHD\$>D\$DDkDfAJAfAIAE9$I$LE HPA$DuEtWE qE1E9vEIkH]CuOE{P[HL=HCII$H[]A\A]A^A_ HCLp(1AD}IA9vEH}N M;$tLAII1EQD}MփD9IEtIFA)}DkE1D9w;ff.UHAWAAVAUATSHH(dH%(HE1~IvHH1HIHIMAIQMIL)IIL9tHH$ALl$HILCD LH߹8HH:HHHHEz0D8'HIH{(DLIHL{(HULILAOpPjAMELLALH5ZYH3HF H9IHHudH34%(uHe[A\A]A^A_]L)JLDAVAUATIUSHH NdH%(HD$1 H=\։HcH>I|$(wIAMAt"I R~ڀ#:$u A[1.Iff.AWBAVIAUA"ATIUSH DG1E1E9~v>MD1HI{uc|$XtH|$ tTL8HH0L8MGDHHA?Auswn{'H|$ %{%{t<%D$1ML/ƃ܃|$Xu+&D\$XE9t$EEEDL$XH|$ (u'D$X뒃|$Xu$H9T$(?(LI~-({#(L8LƺH#L8DIA 4(AH=W('LHLT$hLD$q/LD$LT$h@tWAL1H1M}H|$m'A7'H$dH3<%(uH[]A\A]A^A_J'I,H3L8LT$LEuRH{(FhG DO<HHHHD+PAAt15}LD$S,AEAf.UIHAWAVAUATSHHHLGdH%(HE1Lg HIH9tHH$H0HL$(1E1AL==gI|$LI$Ht$HHIDŽ$H)HAR8AR8L9D+AAOc4M>A1DsCLkAAMcMM9D9DAL4ZLCME1ALkDsFA/IcD)LHsPu~tDsBH"LcF\+ArAHu)HyAIHL)NlH)LHDs떉D9Ds|AfBD1gDsBH"LcF\+AsAHuAJ8˃A E1A EZ8HUdH3%(uHe[A\A]A^A_]LkAVIHAUIATUHHSHDAAHpdH%(HD$h1HLqAA8HLd$ LιLA$H<DT$XAA E AADT$XHD$HLLE1LLD$1ER1AVL\$ASAVsH H|$Aąy(DHt$hdH34%(u7Hp[]A\A]A^Lt$E1B JTA C4rEI9r\,fAWAVAUATIUHSHHDjEOH@v!@uCIHL?ILLaHtMl$LHA\$H[]A\A]A^A_IMl$L|LLL@LI@ MM)I@wL[IMkICHHJ\느UHSHHwdH%(HD$1GG,O7wx8)AHH5qJ|LHrH{DKFADTD[BD ȉD HToHEHL$dH3 %(uH[]úx)@AWAVAUATUSHH $HfopdH%(H$1D$II)$H$IHD$1ALH|LH)>HHwHuHtLHxLAƅuRHMIHHLLLbH$dH3 %(DuH[]A\A]A^A_MAWIAVIAUATE1USHdH%(H$1HHT$@D$ HT$H$IcHIL,H<ـ?@MHAAl$A9.H$dH3%(uH[]A\A]A^A_ f.USHHHt$(HT$0HL$8LD$@LL$Ht7)D$P)L$`)T$p)$)$)$)$)$LL$ H1IdH%(HD$1$MH$D$0LL$HD$1Ht6L<$HHt/wA<$MI;L\$MKLL$H~H$HHL$ HT$HHH$D$0HL$-HH\$dH3%(u H[]ff.III1HtAHLLHHDIA/wDAHrDH6HrHNHJALfDHXHt$(1LD$@ILL$HLL$ HT$0MHL$8dH%(HD$1$HD$`LL$HD$1Ht5L$HHt/w׃$LH?H|$L_L\$HHt$dH34%(uHXfHHt$(HT$0HL$8LD$@LL$Ht7)D$P)L$`)T$p)$)$)$)$)$dH%(HD$1HT$ HH=J(H$HT$H$D$0HD$IH(HL$dH3 %(uHDGATUSH HH HHHHAlHd1E[]A\SHHt HH[ff.QH=$(Ht UH=(Ht ?H=((HQZ$@SHHt HH[f.fHAQM>HfH5j(L;MHff.AWIAVAUIATULSLHH$pHXkAĉHD4HQHþLHCHPL|$~D$HLs $H,$~ $DchLkL$PK@H[]A\A]A^A_@Q1Lj9t(AA)AE1MICH9rDAsԉHA H9}PZATAUHSHHDHH߉[]A\9fUHSHHPYHH߉[]ff.AWAVAAUIATUSHHLg uHG(KdHH9e{hL iAAHCC8HHLϋOHH A)AAʋO ADE)EJ<L8H<$I8HHt-HT$LSHT$L tiH4$shHCE1H}M1AJHAJ H )DLAADD)ω|$D|$C<EM9rE)EJ,H4(H>Ht"HNL$LSuAHCL$ENMNHC(NHL[]A\A]A^A_EuNLCIHsI;NLc f.AWAAVAUATL%XhUSHDGhG8MIMAHHH )AH ALGA)EKHH4$ILw HtT$ H4$HAUu~EMhMET$ IMAt$AL$ E$HAHjH )A)A/AE<IL9rE)DIHtHtH4$HAUuME1HH[]A\A]A^A_AWAVAUIATUSQLgLw HG(H+G0ohH<KL9KM9H5gHD4M}XMxMLAU@H\MI}0Mu MAmhH-fIEI)}(IE0M;IL9M>IvLAUAuhAAHHDNN >MI D)DMMA)EOLMMtILvMU LƍpI D)D)ƍ2HI9wD)҉MI HHHulLI]HH8LLӸZ[]A\A]A^A_fDH4RBH )Dž'$\-4RB5))1)) 1A))A AD1AA))AAE1DE)D)D1ى)A)1A) A1)D)AD1ff.AUIպ ATIUHSQHG(H+G0HH HBH9G vH]HM H,H;v LHAԅt HH9wX[]A\A]ATUHSHLguHUHHt4L[HuHH]A\G XHcHxIUHSHQhHHH8SH H@Hu1Z[]HPHtGW1DAWAVIAUATAdUS1HH/ HT$aI(tAD{Ht$IcIlHA։Åu$HmIcHtD9VIlD{HmLH[]A\A]A^A_ff.ATUHSH}HHt7HH8Su*H HSHiLaHVHs0H;S(HuL#[]A\H+MtHuHuLeHf.USHH(dH%(HD$1HH#u/H$H9s&Ht HT$HVH$H@HD$dH3%(uH([]@H=(H=(uP1H(ZfSHtHHuH1HV[Hf.fATIHUHSHgHH9vHH<1H)LHHH[]A\f.@UHHSP1HHHHHHZ[]ÐATIUHS-HcLHHHH[]A\f.fAWHAVAUATUH-Y^SHX^H8dH%(HD$(1H|$Ld$oD$HVHT$ AAH|$?HwHt$?%uLt$H=]A6AHVA*V LLqE|Ll$A}.I}VAuHAHAEEoA3wAENc I>AD|$A/wgEALT$ D|$I:H1HHElHD$Dt$A/v:HD$H\$(dH3%(Du8H8[]A\A]A^A_LT$MZL\$ADt$MmLl$/fSHHHDHdHt[DHt޿H(H5ҋ(HHHH1f.fH\@H(HHfSHH߾[D釽H\@H\@H(HH)fH(HH fHE(SHHHH߾[gH=(SHHHH߾[7PXH,HՊ(H5(HHHH-xUSHHH-p(HtH=D(OHX(H{HtwLKJ4H9wjHJHH9rDHH9sHHALBHuH9tkIHH H9tLH@LKHCIHxHSH=(HtH=(uwH[]fILHFLHAL LKHz(H@HCH=k(1HL](PHLN(H>yH(H59(HHHHHRf.DUSHHH-(HtH=(H{H(HHCHHHHH9w}H H9v0HHXHuHtH=P({u_HH[]DHHH{H)Hv$H HyHH1HHHf.H H81HH(봿~HO(H5(HHHHHyQfH=(Ht H觹H(Hf.DSHH茾Ht7HxHHHH@xH)1HH[H8Hu f.@H(HǀH9vH (H9sHgHf۸f.Hp޽HHt6HzH1HHHBhH)pHHHfDpHHu9 fHe(H9v Ha(H9sHHfD+f.f.H(HHfHW@HW@SHH߾[%DSHH߾[Df.SHH߾[Df.SHH߾[Df.'f.ATIUHHSHHdH%(HD$1HH$HPt H$HH$HEHHHP tH$I$HL$dH3 %(u H[]A\葸I@PtWH NLVIcL>LHBMtpHDI@x(MHHBHLH@LDMMHDHE11HDXMAIM ExDHBzDHBk@LcHB[@HE11HDXMAIM Ex? A@IIM DLHBf.HI(dH%(HD$1@t<tfvH9IILHLd$hHL$`LH@8H([]A\A]A^A_I,$AT$Mx*L1H9DAD$H(1[]A\A]A^A_DIuAD$IqH9t6A*hHHL$LL$T$T$LL$HL$HԼHHv fDH{HGSHcHsHԼH HHvHuAH0H[@DCعD)AHEHωK؃hH9tHSH0HSH[nf.@HH8Ht%HԼHWPHw'W(xt3xEW(HÐuHO HfHHPH@HW HPHHf.DHS@HfDH3@Hf.HfffdH%HHÐHfffdH%HHÐATUSHdH%(HD$1=(x(۝HHX1HL$;*D$11HHڛ0H-Ny(H=CIHMVT$Hut:HҤHMH=mC(D$::L蘤fDHx(-H=pCHb:Hx(H=BH軨覡fDOweL dCAKcL>HtEDG(D;G,};IcAL @HG J@DG(0HPHHHtHu1HOHDARtAOt DOH AQARu AQHWHHHO1?ff.@HAUIATIUH-CSHHD;OwHcDH>fDH[HuH[]A\A]@H[fHS:u A$HSLLH[DAEHSDHAUL,ATUHSHHH,f.HHHHD$DL9t>DeH=uHƃHH@1@H[]A\A]Dff.@H7nt}A< E1HE1AAfADH)‰AD9|/CH7AD@ЍQЀ vκ0)EDED@ADfDHFHNQЀ wHApE1fSG(;G,}7HcЃHH RHWHCGAHHCH[Ð1H[fSHWH<_t)HsLHuH[HufD1[]A\fHsLTHt߃8/u[]A\D1ff.fAUIATIUSHHHBHjRHDH9w4u#H{LH;LΛHLHCLcH[]A\A]fuHt/HH9wH;H轜Ht HSHk@HwH;谖HHCHCCHG8L3HPSHHWH_ZH8'LK<A nuIQ=HSAIIрEII@H@HK9@EuAE)ȋS(;S,HcʃH61H5Et1@H1HOfA:D$2HC8_(HHCMHEHxcA<$f4H IŹH=LH= LtH=&LHIHC8ILL8H7H7HlfDH H6HcH@HI5HI*H1Pv r<HIEHIEHIHI%HrHHHCRLHH?IxiHEHHC-HHC1@AUAATUSHHdH%(HD$1HGHH$@80u41H¾.HHEHt)HhHCD8(t@DcLCLHDcLHu1HT$dH3%(uZH[]A\A]HHCH$f.HHGHD$dH3%(uH11Ҿ.[]A\A]{ff.AUATUSHHHWLg@dH%(HD$1E;HHl$Hs+HE8)H@fDHHHCC(;C,}gHcЃH RHS C(H}H HHAADHMHsI1x1rH 耈HxSff.AVAUATUSHHHwdH%(HD$1HAkLCLHkL1ɾBHHxH$HtHS:tHJHK:ED1H|$dH3<%( H[]A\A]A^DH1H+ HHtHCH߀8FtgHEHHt H$wHJHBHEH$HMH$HwS8;S<kHK0HcHS8WDkHHEfHH$@H'S8;S<HK0HcHH$S8HHHs 1ɾ(HH.H$HL(K(aHcHH;K,fHcHH<@HC H@K(HPR'SHHsv@HHHsH$HHC8IHH!HHH$HHkH$}ISPHS8;S<HK0HcH1ɉS8EPwHHkHHH$HH$jf.F0H$DHHHs01ɾ$HHH$DHHHs1ɾ&HHH$UDH H$?HFHC~VHFHCFF<0?H(HcH>HHHsx1ɾ%HHVH$DH~H{F<_0H< v DHHNHKF0< vIȋC(I);C,HcЃL RHS J,EC(EHEH}DEFH<_d@HH{HH*HHH$@HHHsHHHlHHH+H@H$~_tHHHHC8_HHHC H-HHH$`S(;S,HcƒH @HC HH +L(@S('HHCHPS(;S,PHcƒH @HC HH K(@S('HHCHS(;S,HcƒH @HC HH K(@S('HHCHS(;S,HcƒH @HC S(HH HHH@H1ɾJHHH$8S(;S,HcƒH @HC HH #K(@S('HHCH(S(;S,HcƒH @HC HH J(@S('HHCH S(;S,HcƒH @HC HH I(@S('HHCH S(;S,HcƒH @HC HH I(@S('HHCH bS(;S,THcƒH @HC S(HH ::HHH@#C(;C,HcЃH RHS H,1EC(H,$E,F0< fUw H{AH,$H%HEH$HxH{HCt HPHSsH$fPDHPH$Hc83WD1HHHCH$HHuHH$DcLCLHDcLHHHK{HEHDs(Dk8HCDcHHS:ItHkH$Ds(Dk8DcH|H$Hs8;s<HK0HcHHH߉s8H$9HDcLCLHHsDcLHp}ff.fUSHHGDEtHPHWxD1۾C1L=()щHcH IMID8 t~T9u1H[]D8YuW(;W,}HcƒH @HG H@W(1L@H[]fDPHPHHWXAvu]C< K{U(H;U,vHcHE H IH@U(HQH20HpP:AcvWL1_PGP6uP1H…t4H ]PH[]þ3H@USHHWdH%(HD$1H$DBCHHH5{HKD$C(;C,}[HcȃH4IHK H,EC(Ht:AD$w0HEHCDeHU^@A1ODHC1@HCtH81ɾH@1xHtHPHSxn1ɾHHbHHHHH8D1H1ɾHH{/8HS:+LRLS:_DX1A $AB.H81ɾ HfH1ɾHfH1ɾHfHH{HHC8_HHHCCHH H~vH1H1ɾHMfhHm1H1ɾHf1H@1H.1H1ɾHHh1ɾHfH߉KH1ɾ H H߉KH1ɾ H~H1ɾ HdfHh1ɾHDfHRfA 2H~$tt HAA9C(;C,}eHcȃE)HHE88?HUHBHxcO9HMDHkYHE81T?H@L-HULH0HRu :@DHXHUH=ĪHBLL;Hu/ƃHHH@HǃHDHHPH[ƃ[HEHPdBHu/ƃHHH@HǃHHPH]ƃ]HE81urH@xuhH@8>u_Hu/ƃHHH@HǃHHPH)ƃ)fDH$dH3%(A@H[]A\A]A^A_HVL HpHAH H6L ǃ0@ǃ0HuHE1Hu <AՃ8/'Hx'H@AUHuHEDl$AHD$H-#f.AE9D<HT$DH@D9|$~HLA,-HHIHD4DL9tE0H=uLD$HHƃH@1LD$L-3HAnM}4fHHHD4DM9 EuIH=uHƃHH@1L%zHA{Mt$ 0DHHHD,DM96 E,$IH=uHƃHH@1L-HA{M}1fDHHIHD4DM9 EuH=uHƃHH@1L-QHAgM}1fDHHHD4DM9"EuIH=uHƃHH@1L-HAdM} 1fDHHHD4DM9>EuIH=uHƃHH@1L-3HAgM}1fDHHHD4DM9!EuIH=uHƃHH@1HUH$H51HkH H!%tDHJHDщHH)HLd+DHHHHD,DI9DmH=uHƃHH@1L-dHAtM}1fDHHHD4DM9( EuIH=uHƃHH@1HmHPH=u+HƃHH@1H@,@HUDHI;HUDH:;L-HAjM} .HHHD4DM9EuIH=uHƃHH@1HEE18'h'Hu/ƃHHH@HǃHDHHPH(ƃ(HU@:HH=*HPH)ƃ)}=,A+HUDH9_HUDHA L-9M}H1fDHHIHD4DM9\EuH=uHƃHH@1LmHmAE1&39Hu/ƃHHH@HǃHDHHPH(ƃ(IU8HHPH=u+HƃHH@1H)ƃ)HDHMHUDHLL-HAoM}4fHHHD4DM9EuIH=uHƃHH@1L-KHAoM}1fDHHHD4DM9EuIH=uHƃHH@1LeH-HAoL}El$0DHHHHD4DI9DuH=uHƃHH@1HUHmHt DH6HHPH=u+HƃHH@1HDHH{ƃ{b6HHPH=u+HƃHH@1H}ƃ}}HUHt DH5H}^LIv.B+LHHH@E1HǃL5A,IN/DLIILD<DI9YE>IuƃHHA1H@H f}#HUHZ%(H9BDH5HHBHu+HƃHH@1H ƃ f}H-A_Lm1fDHHHHD$DI9DeH=uHƃHH@1HUDHHl$(H(D$0HD$ HD$ H(H HD$83t$0#HD$ H(CHE8:H@8;HUHMDHIHELuH5LhH@LxHhIFH8^U1LDH}HLDHGLDHaHHߺH5-HDH?Hf.H(Lt$@H Hl$HL(IHL$@LD$PHD$XM/IGm/LAHPwPD@Eu?A&oDAH)D@oHHL@I )LPH(@HHuHUHDC2|$PL(DHIAtIVDHAI 2AuH(HUDH}CXL-jHAnM}1fDHHHD4DM9EuIH=uHƃHH@1L-HAhM}1fDHHHD4DM9~EuIH=uHƃHH@1L-HArM}1fDHHHD4DM9EuIH=uHƃHH@1L-VHATM}1fDHHHD4DM9VEuIH=uHƃHH@1L-HATM}1fDHHHD4DM9 EuIH=uHƃHH@1L-+HAgM}1fDHHHD4DM9. EuIH=uHƃHH@1L-HAjM}1fDHHHD4DM9 EuIH=uHƃHH@1L-HAcM}1fDHHHD4DM9 EuIH=uHƃHH@1L-nHAvM}1fDHHHD4DM9 EuIH=uHƃHH@1HED8Eu E1"L(#9U$ LD$ HD$ Hl$(H(H D$0HD$8HUDH,DT$0EHD$ H(E4L (H(HD$ L(MzLD9kHH\DpEuHPzvE1=LcmHmMHI&HHHHD$DL9DeH=uHƃHH@1HUDH+HH=^HPH>ƃ>L(LpmHEL(Hǃ(HH Lt$@HD$@L(JHD$HD$PHt$X3H HMF AAHH@H%AH(I@AL(IA@JIp3-LI HHuHUDHHD$(HD$8u HD$ H DHLEu_HHPH=u+HƃHH@1HHUDH ƃ 8(H I9uL(HUDHd'HAHPH=u+HƃHH@1H.ƃ.LmA}F>LDH&XALcmHm.M=HI'HHHHD$DI9 DeH=uHƃHH@1HUDHA[L-SD&M}H2HHIHD4DM9EuH=uHƃHH@1L-HAcM}1fDHHHD4DM9EuIH=uHƃHH@1L-xHAVM}1fDHHIHD4DM9bEuH=uHƃHH@1L-HAvM} 1fDHHHD4DM9EuIH=uHƃHH@1Hu/ƃHHH@HǃHDHHPH~ƃ~HU#SL-AHAtM}4fHHHD4DM9EuIH=uHƃHH@1L-HAtM} 1fDHHHD4DM9NEuIH=uHƃHH@1L-QHAtM}1fDHHHD4DM9 EuIH=uHƃHH@1HPHD$ LD$ H(H Hl$(D$0HD$8H7.@HUDH"|HUDH!hHUDH!THUDH!@HUDH!,HUDH!HUDH!HUDHA L-x!M}H*HHIHD4DM9t:EuH=uHƃHH@1HUDH hHUDH THUDH @HUDH ,HUDH HUDH HUDHA-L-x M}H*HHIHD4DM9t:EuH=uHƃHH@1HUDHhHUDHHHPH=u+HƃHH@1H]ƃ]HUDHHUDHqHHPH=u+HƃHH@1H)ƃ)HUDH xHUH$H5'1HMH H!%tDHJHDщHHH)tiLd(fDHHHHD,DI9t:DmH=uHƃHH@1HPH=u+HƃHH@1H}ƃ}^HUDHA)8L%Mt$8H-fDHHIHD,DM9t:E,$H=uHƃHH@1뫋UH$H5t1HUKH H!%tDHJHDщHHH)tfLd%HHHHD,DI9t:DmH=uHƃHH@1HPH=u+HƃHH@1H}ƃ}HUDH/HHPH=u+HƃHH@1H]ƃ]JHUDH6HUDH"HUDHHUDHIl$MQwNHPH=u0HƃHH@Il$1H ƃ IcՀ| uAIcHHLl)HHHHD$DI9JDeH=uHƃHH@1HUDHHpHtH HD$(HT$ HT$ H HU:DHKHpHD$ H HDH@HUDHL@L9@fL9YILIHEHD$E7AED$}/L(HH-A_Lm1fDHHHHD$DI9DeH=uHƃHH@1LchHhMHI)HHHHD$DI9RDeH=uHƃHH@1Nd-I9wk fHHPH=u+HƃHH@1HD,DHI9LDmH)H~A_u}_u}UuLuM9s10HHIHM9VAHЀ vۍH7H-oAtLm1fDHHHHD$DI9DeH=uHƃHH@1HuHH 8/%H DHHUH HH vHUH$H5%1HEH H!%tDHJHDщHH)HLd.HHHHD,DI9DmH=uHƃHH@1H$DH5P1H4DH H!%tDHJHDщHHH)tmLd,f.HHHHD,DI9t:DmH=uHƃHH@1HPH=u+HƃHH@1H}ƃ}HVAH@FJ3H HAt}DAIHLAWH(AHfoT@I )fo\PH)_HDHH@DPHtXJ3!LHL1H Auǃ0HRDH+Hpt HD$ H H HHPH=u+HƃHH@1H>ƃ>H@DhEA AsHEex[<RH@<0<1;H57Hϙ:f.IEH=UL0Lu h8 H=L€҅ZH=L DHL&H=L#H=*LvHu/ƃHHH@HǃHDHHPHH(ƃ(HH=u&ƃHHH@1HPH)ƃ)L-HA_M}2HHIHD4DM9EuH=uHƃHH@1HƃHH@1vHHN HBH ƃ 7HƃHH@1HHw HBH ƃ HDHHUDHHUHKDH;L-A:M}3HHIHD4DM9EuH=uHƃHH@1ƃHHH@)ƃ)}=HǃHHPH-ƃ-HH=u&ƃHHH@1HPDHH[ƃ[HUHH=u&ƃHHH@1HPH]ƃ]HT$ Ht$ H HD$(HUDHyHƃHHH@HǃAH-HA{L} 'HHHD4DI9t>DuHH=uHƃHH@1AEH$H5fHP1G;H H!%tDHJHDщHHH)tbL4*"HHHHD<DI9t:D}H=uHƃHH@1H-A}L}'HHHHD4DI9t:DuH=uHƃHH@1Mmǃ0kHDH XHD$ DHHL$ H(H Hl$(HD$8D$0 HD$ DL$0H(E Hu/ƃHHH@HǃHHPH H(ƃ DXHPE~7H;AHHWHHHHH;BH9uD;\2 IcH AHDXHHHHtZHchDlA9 yHDOHA9 DL`LVIMQL H6LHủhHHpHE1H /<iH蛘H Hv r<DHZHu/ƃHHH@HǃHDHL-M}A>HPH<ƃH5ӜHhH5HOHu/ƃHHH@HǃHHPHlƃlHu/ƃHHH@HǃHHPHuƃuH5HzHUDHH5iHRHPzHR:>Hu/ƃHHH@HǃHHPH(ƃ(HE/H@HeHUDHB|$PL(-HE8HU:)HDHHHu@HxtH@Ht8/tH$1H5H01HHHHHIHI&HHHHD,DL9DmH=uHƃHH@1HB8)t ǃ0HRDH;H5HI}tgLDH Hu/ƃHHH@HǃHHPH ƃ LDHHHDHڿHUDH{LDH鸿DHr3*M9H<_Hu/ƃHHH@HǃHHPH@,@LrDhǃ0 Hu/ƃHHH@HǃHHPH-ƃ-HUELDHH5rsHpUHSH(dH%(HD$1HtjBHӃ_4QH$CHH4HHD$HHH踻HD$HHk4Dž0HD$dH3%(uH([]R(fL* AWH AVAUATAUHSHHHcH>f.(tMHHPH=u(HƇH@1H ƃ HUDHH-LmA:H,HHHHD$DI9DeH=uHƃHH@1HRH[]A\A]A^A_fHHHBH ƃ DH?HHBH ƃ DHHDHHPH ƃ HU7AHu,ƇHH@HǃHHPH*ƃ*[L-`HA M} 1fDHHHD4DM9EuIH=uHƃHH@1H-HAcLm1fDHHHHD$DL9DeH=uHƃHH@1H-IHAiLm 1fDHHHD$DI9DeHH=uHƃHH@1H-HA Lm1fDHHHD$DI9DeHH=uHƃHH@1H- HA Lm1fDHHHD$DI9DeHH=uHƃHH@1H-HA Lm1fDHHHHD$DL9DeH=uHƃHH@1HHPH=u+HƃHH@1H&ƃ&H[]A\A]A^A_ÐHH-arA&Lm-fDHHHHD$DI9tDeH=uHƃHH@1@L-OHA M}1fDHHHD4DM9>EuIH=uHƃHH@1L-دHA M}1fDHHIHD4DM9EuH=uHƃHH@1H-=HA Lm1fDHHHD$DI9.DeHH=uHƃHH@1HUHHHH=u/HƃHH@HU1H(ƃ(DH+HHPH=u+HƃHH@1H)ƃ)H[]A\A]A^A_@HUfƇHH@HǃƇHH@HǃƇHH@Hǃ AVAUIATIUSHHtPIuILPu1HP wHH10HHuL(L1ɉHǃ(HHHtwHBH(ƃ(I$HtHNHH=HPHLH)ƃ)#L([]A\A]A^HƃH(ƃ(I$H@HǃHbuHƃHH@1IHу(H=HPH1L(L(Hƃ(Hǃ(1HH=HPH)ƃ)sH uH=tUHPH Hƃ H=THƃHH@1(ƃHH H@HƃH)(ƃ(fI$H@HǃHAWAVAUATUSHHdH%(HD$81HH0AHAI ]IrBHKCL H )*teDHL HHt`0uVCuHSEuH3vHKCL H *uH HDHL DHD$8dH3%(]HH[]A\A]A^A_H HDHL L(HRDHHDž(L(HAHPH=u+HƅHH@1HD.ƅ.HCLhAEF3w0H Hs MmA}O3w HHHuLDHL L-A:IM1DHHIHD|DL9ZE}H=uHƅHH@1ҸH kHRHA{HK 'HHHD|DH9tDD;HH=uHƅHH@1ҸH AEH\$H5HߍP1Hڋ H!%tDHJHDщ@HHH)thL<!HHHHLI9tA H=uԈL$HHƅH@1L$HA}HK'HHHHD|DH9t@D;H=uHƅHH@1ҸH MmAEezf.AWHIAVAUIATAUSHHHt)fDP-HHu1LDH5HH=*HPH ƃ HtcHBH[ƃ[IUHtDHHH=tzHPH]ƃ]H[]A\A]A^A_DHƃH[ƃ[IUH@HǃHvHƃHH@1ZH@8*uwL1DHHHƃH [ƃ[fIUH@HǃHH-3HA HM-fDHHHHD4DH9tFDuH=uHƃHH@1ҸH DL1DHHHt HBH)ƃ)DƃHH)H@:1t fDAUATUSHHBLchHhMtuHHI(fDHHHHD$DL9t>DeH=uHƃHH@1@H[]A\A]D0ATAUHSHHHPH=HDHH(ƃ(HHPH=u+HƃHH@1H)ƃ)[]A\@HCHOHƇH@1:ff.HBH:f0AWAVE1AUATUSHHLhHHA};H $uD<HLJ<BH=uHƃHH@1ҸLfDH$HLfHƇH@1ƃHHH@Hǃ!ff.UHAWAVAUIATISHHD7dH%(HE1A_~H=qHE1HHHH DžHHcHRHHH։,HDžDž(H)HDž0HHDž8Dž@H9tHH$H9uHHt$IHHIH%H<I)HILH9HH$@C$<;HHC LHBMtpHDI@x(MHHBHLH@LDMMHDHE11HDXMAIM ExDHBzDHBk@LcHB[@HE11HDXMAIM Ex? A@IIM DLHBff.@t5p@ tAv@@t)@Pt@0u5HD@t@u1fHHPfHǁ H9n UHAWAVAUIATISH8IHHH?IH9HEIE1AHEL=pAPfH_@tgtyHDI9vII$HH?IH9rHe[A\A]A^A_]D?HI$`HI$H@?<wHHAD@?H11Df.HwHHH @xI$X<CIMACI,@11@HSHЃHH ƄxIHfDE$pLLEDD]D]HMHHD^LEAAPHHEI$Hf.GHI$`HI$HoGHI$`HI$HGGHI$`HI$H 11@HSHЃHH Ƅx11fHSHЃHH DŽxI$XHHI4H8H@11@HSHЃHH ƄxHkHHAD4^fD11@HSHЃHH ƄxH#HHAD4fD11@HSHЃHH Ƅxk11@HSHЃHH Ƅx11fHSHЃHH DŽxHHI4H8H@qMLM )HLHI$ H?I$ )LHHL HI11@HSHЃHH ƄxI$011HSHЃHH ƄxI$(HADŽ$@f11@HSHЃHH ƄxI$0HADŽ$@a11@HSHЃHH ƄxI$(H-DI$811ADŽ$@HSHЃHH DŽxHD11@HSHЃHH ƄxHwHI4@H11fHSHЃHH DŽxH}D11@HSHЃHH Ƅx11ɐHSHЃHH DŽx?W@NLHHH =f11@HSHЃHH ƄxI$011HSHЃHH Ƅx?w@t LHHH I$XHADŽ$@I$(f.11@HSHЃHH Ƅx?w@t LHHH I$XHI$(.fD11@HSHЃHH Ƅx11ɐHSHЃHH DŽxI$XHHI4H8H@11@HSHЃHH ƄxHwHI4@H11ɐHSHЃHH DŽxHMD11@HSHЃHH Ƅx11ɐHSHЃHH DŽxI$XHHHI4H8H@D11@HSHЃHH Ƅx11fHSHЃHH DŽx?@LHHH }HH9tHH$L)H$HHD$Hff.f5(/()(#(((( ((((((((((@AW01AVAUIHATUSH8HIDžIDžIH|IHIH?H|]=IHIMFMHHIcFI)Mg LA eID)A0@OE110HHHI @xL`1E1 HHXsHHI @x?w@t HHI LX11@DHSHЃHH ƄxHhƅqA$E1fDLSH fD?oHcLT I9wgHcHD H([]A\A]A^A_f.HLcSH@DSH@LSHDSHpLSHXDSHHȊ}HcLT ?~#TCHS<)<<7MHDSLDDT$ DT$ HSHL$HD:LT$L 0HL'D11@HVHЃHH DŽxE11HD^LڃHI Ex?w A@HcA8IMt A>u HI‰Hf11@HVHЃHH DŽxTHcA8MMtA><(MHE11HFHǃHI x?w@&p܈HcA IMtA)骈f.PHcAMMKA<@HfDDRЉHf.HCH\(HCHcH| H[HD}AHcHcLT HL AEKcL>DMUHEHcHcHH| L\ LT L\ LT H| wUEHHcHHL H| H| HL ESHKHH9:H)ЉHLT EHHLT {HyDEHHLT D@E11HVHЃHI „x?4@+HHHI @HE11HSHЃHI „xfD f.u MHuLHH?I1I)~fDHE11HVHЃHI ÄxMH:HHI HHI <WEHf.IHIHEHI)HL1HHILHI HIHIHIHIHvI!HkLHHHIXI9HAEEI1H:I9HAE'I9HAEI9HAEI9HAEI9HAEEHHff.@AWAVIAUATUSHfofoOfoW fo_0Ht$fog@fooP)D$ fow`)L$0fop)T$@fofo)\$Pfofo)d$`)l$p)$)$)$)$)$)$HfofofoH>)$)$)$s $u H|$XA@tAƆHD$IF8@u\HD$H0HHv'LT $@t u ՂMHD$L(MQ@ZHD$11H8HWHЃHH ƄxHT$ H1^IHD$ ML|$1H$L-H@Aw=AGIcDL>f.IH5'L<AƄIHIHuIH\$HH?stHH?IH[]A\A]A^A_I?11fHWHЃHH ƄxH$HLfIiAƄ[IHc€HD I2I?11fHWHЃHH ƄxH$HLH5o'<ILI_H50'HD H$uH뙀='IHD$$@tƄ$HD$HD$XAU1IATIUSHHHHl$HHH$HH@HH=0'H5#H=L'us=S'Ll$@tƃHD$HHDŽ$PHC8HDŽ$@HDŽ$8:LHĘ[]A\A]D='u''''''''''''''|'v'p'ff.UHSHHHhHH|uHǃH[]~HH' H@t u i~HHH[]fAWIAVAAUATIUSHHICH$PHt ILI$ЃthuEudLHILH1HHH?H)I9L$@tHĈ[]A\A]A^A_M7}ff.AWAVAUAATUHSHHLwLHT$Ld$cMIHپ AօH$`Ht"IHH AƒtxuSLHI LHA…tu-HAuDT$MIHپADT$t AHĘD[]A\A]A^A_DHD$L(ff.HII@t u Ix81L''fDHtA<1|H2HHAII4 |AuH@H@tH9tA s,t>@:ttft fDH>HH:L\>L\:HzHH)H)HH[f1A@uIy8thHAtHÀ='I6{HD$A@tAƀHD$I@8>ɉ:tt e'I@8A@uzHI+IdAtDHzHcH'0H@uzHH7tHÐH@HRzHcH'0@uH </zHH@7tHHff.fH@HH?H@H@H@H@H(HH$HtHD$H(ff.fH@H@U1ISIHHxHH$HHHHL$H@H$$0H1HD HHHt*NtuHHHD HHuH$HEH$ fH$XfH$HEH$hHEHxH[]Hx1[]@f.UHAWAVL`HuAUILATL@SHPRPHhHUnfo`fopfofofofo)Pfo)`fo)pfofo)fofo)fo )fo0)fo@))))))) )0;udHEHt ILIUЃtPu;LHLHUuH]LeLmLuL}f.ffo`HIELfoHHL)PfopH?fo)fofoH))`fofofofoIM)pfofo0))fo))fo )))))) fo@)0HLLHHL1HHt&H@ HH-H=wHHLDHEHL HUH]LeLmLuL}HmHYff.UHAWAVIHuAUIATLSHLRPHHU&foHfofofoLkLfo fo0LsHfo@)foPL)fo`fop)fo)fo)fo) fo)0fo)@)P)`)p)])e)m)utH]LeLmLuL}LLLhH`HL11HHt,HH=vHH-H=wHHLDHEHL HUH]LeLmLuL}HmHYfDUHAWAVHuAUIATLSHRHPHHUEfoLfofofoHLfo fo0)fo@)foP)fo`fop)fofo)foI}) fo)0fo)@)P)`)p)])e)m)ucqLH/LhH`Li1HHt7HHv"HHHwHHLDHEHL HUH]LeLmLuL}HmHYVfUHAWAVAUATSHRPHHHULHuLLZfoLfofofoHHfo fo0)fo@)foP)fo`fop)fofo)fo) fo)0fo)@)P)`)p)])e)m)uSoLLOLhH`IL1HHt2HH=vfDHH-H=wHJLNLHEHUH]LeLmLuL}HmHYH]LeLmLuL}DHGHtHfff.@UHAWIAVIHuAULPATL`SLHxHUDfLLAׅu&t&LLLL(Åt҃tͻHx[A\A]A^A_]@HJH9Nwf.AWAVAUATUS\ H(H|$D9IIE`DMLL$H|$ILL$ALL$L$xRI7HcHH|$IH3AօyLHBMtpHDI@x(MHHBHLH@LDMMHDHE11HDXMAIM ExDHBzDHBk@LcHB[@HE11HDXMAIM Ex? A@IIM DLHBff.AVAUIHATIUHSH_ fۉHIUHInA|$ LHUHL$f@OHt$H94$wH[]A\A]A^UHSH_ HH MHT} zt1H[]f.HzyHzx f.HHBxxf.HxxH] fHxxU Hl$Ru!DfDLtHHRt%Pu8HPH1HJRuH[]HB:zHff.@AWAVAUATIUHSHHH8DG fAED 6IHD$ E1HD$HD$(HD$Af.HCHSHD$ HT$(HtLH)H9H\HcCtE t2HSH)L9t&HHT$HAHT$IIEtEHL$HSLDDL$HL$D1HƒDL$DHw HHHD$ H>LHT$(H)H9*H8H[]A\A]A^A_fH81[]A\A]A^A_ff.@AWAVAUATUSHXJ(HGLt H/>HHD$E1OfH<E1E11H)E11AH<#PtdlLDH8H9t<uLHH ML9rLX(ML9MBMBIBH8H9uH'H/vAH'Mt"H\$HtIL$(L%'HK(ID$(LLPHhL@ L0LhHH]LӀ;WHX[]A\A]A^A_HX[]A\A]A^A_@HO H; ͯ'LG(H 'H u'L&'LHAHAHIH0I9uH 'E1Hv'H'B(HD$RfHHX1[]A\A]A^A_L9'XL'MML 1I $MD$I9rDM9/L IL$(HLII $MD$I9rf.DcHHDmDHL$HSH{I@t {;HUHEHt$H|$ HD$ HD$@HD$(HEHt$8HD$0fHE H"HxHc@H) H؉Hu HL$HVHHD$HEH\$DHDDHL$LHH|$HHHU(HcHH9HHc HH9H9s3H >HLcII9v1H9sLIJcff.ATUSHL%'HMt H='H'Ht H;huH;ktrHHX(HuH'HtrH'fH;/t{HC(H[(HtNH{C uH9uHS(HMt H=l'wH[]A\H(f1H[]A\fDMt H=4'?zf.HS(HHH@'fDuDHHH˺ff.AWIAVAUATIUSH8'HH=@L<$HD$HD$HD$HD$ D$(KsHl$ HtHD$I$HD$ID$HD$ID$H8H[]A\A]A^A_f.L- 'Mt H='H!'HuH[(HtwL;;rLHgHHt_MHCI$HCID$C Dk fAEHDHHUDHH$ID$6fL5'fH'HHC(LHHg'HHP'Ht3HH9s)H9r HH(H@(HuHC(HHt.DL1fH='Խ HcEH}H)DMH='蓽f.@AWIAVIAUAATL%$UH-D$SL)H_Ht1LLDAHH9uH[]A\A]A^A_ff.f.H$1HH/usr/lib/gcc/atexit failed64:../lib64 m64 !m32;32:../lib !m64 m32;OFFLOAD_TARGET_NAMES=OFFLOAD_TARGET_DEFAULT=1install: %s%s programs: %s libraries: %s %s. %s %s%s (C)%s: %m. !m64 !m32;m64 m64;x86_64-redhat-linux%{fgnu-tm: -pthread}GCCBINUTILS/usr/lib/self_spec%:compare-debug-self-opt()GCC_EXEC_PREFIX/usr/libexec/gcc//usr/bin/GCC_EXEC_PREFIX=COMPILER_PATHLIBRARY_PATHLPATH@%li%nnvptx-none/dev/nullGCC_COMPARE_DEBUG../../gcc/gcc.c../../../../bin-fcompare-debug=help-dummyenv_manager::xput (%s) saving old value: %s -fcompare-debug=-gtoggle*%s: %s *link_command: %s 8.5.0--version--help--target-helplibgcc.a.bfd.gold%lluSOURCE_DATE_EPOCH-L-Fcwdobj-oUsing built-in specs. cc1_cpu-lgcc-lgcc_ehlibgcc.a%slibgcc_eh.a%sdisable}}}}}%{!shared: -lgcc_s --as-needed Reading specs from %s %include%include_noerrcould not find specs file %s %renamerename spec %s to %s *link_commandarch_32arch_64tune%(VALUE).ospec %qs invalid.gk-imultilib-imultiarch-iprefix-isysroot-isysteminclude-fixed--scriptgetenvmalformed spec function nameunknown spec function %qsmultilib spec %qs is invalid /lto-wrapperno input files@c-header@c++-headerlanguage %s not recognized-fno-sanitize=comparing final insns dumps%s: -fcompare-debug failureTarget: %s Configured with: %s Thread model: %s gcc version %s %s collect2fno-use-linker-pluginliblto_plugin.so "" |failed to get exit status: %mcc1# %s %.2f %.2f %g %g "-plugin-opt=-pass-through=-l-plugin-opt=-pass-through=kernel-addressundefinedleakinvalid version number %qsUsage: %s [options] file... Options: -iplugindir=-E-quiet-ftime-report-frandom-seed=0-fdump-noaddr-o-.errrb// //@%{c|S:%{o*:%*}}-auxbase-strip %{fdump-final-insns=*:%*}%g.gkd-fdump-final-insns=/dev/urandom%#lx} if-existsif-exists-elsesanitizereplace-outfileremove-outfileversion-comparefind-filefind-plugindirprint-asm-headercompare-debug-dump-optcompare-debug-self-optcompare-debug-auxbase-optpass-through-libsreplace-extensiondebug-level-gtlocal_cpu_detectasm_debugasm_finalasm_optionsinvoke_ascpp_optionscpp_debug_optionscpp_unique_optionstrad_capable_cppcc1_optionscc1pluslink_gcc_c_sequencelink_sspendfilelink_gompstartfilecross_compilemultilib_defaultsmultilib_extramultilib_matchesmultilib_exclusionsmultilib_optionsmultilib_reuselinker_plugin_filelto_wrapperlto_gccpost_linklink_libgccmd_exec_prefixmd_startfile_prefixmd_startfile_prefix_1startfile_prefix_specsysroot_specsysroot_suffix_specsysroot_hdrs_suffix_spec.m#Objective-C.mi.mm#Objective-C++.M.mii.cc#C++.cxx.cpp.cp.c++.C.CPP.ii.ads#Ada.adb.f#Fortran.F.for.FOR.ftn.FTN.fpp.FPP.f90.F90.f95.F95.f03.F03.f08.F08.r#Ratfor.go#Go@c.i@cpp-output.s@assembler.sx@assembler-with-cpp.S@c++.H.hpp.hp.hxx.h++.HPP.tcc.hh-D_GNU_SOURCE %(cpp)@c++-cpp-output@f77-cpp-input@f77@f95-cpp-input@f95@ltotune_32tune_64cpu_32cpu_64%{!march=*:-march=%(VALUE)}%{d*}--sysroot=%R%Dgenericx86-64m64/m32m32 m32;not configured with sysroot headers suffix For bug reporting instructions, please see: Copyright %s 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For bug reporting instructions, please see:%{fdump-final-insns:-fdump-final-insns=.} % after last input file has no effectenv_manager::getenv (%s) -> %s %qs is an unknown -save-temps option%{march=native:%>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}--no-add-needed %{!static|static-pie:--eh-frame-hdr} unrecognized command line option %qsGCC is not configured to support %s as offload target}%{!static:%{!static-libgcc:%{!static-pie:%{!shared-libgcc:%{static|static-libgcc|static-pie: --no-as-needed}%{shared-libgcc:specs %%include syntax malformed after %ld charactersspecs %%rename syntax malformed after %ld characters%s: attempt to rename spec %qs to already defined spec %qsspecs unknown %% command after %ld charactersspecs file malformed after %ld charactersspec file has no spec for linkingspecs %s spec was not found to be renamedswitch %qs does not start with %<-%>spec-generated switch is just %<-%>spec %qs has invalid %<%%0%c%>spec %qs has invalid %<%%W%c%>spec %qs has invalid %<%%x%c%>spec failure: %<%%*%> has not been initialized by pattern matchspec failure: unrecognized spec option %qcbraced spec %qs ends in escapebraced spec body %qs is invalidbraced spec %qs is invalid at %qcunable to locate default linker script %qs in the library search pathserror in args to spec function %qsmalformed spec function argumentsno arguments for spec functionsystem path %qs is not absoluteunrecognized command line option %<-%s%>; did you mean %<-%s%>?unrecognized command line option %<-%s%>cannot use %<-%> as input filename for a precompiled headercannot specify -o with -c, -S or -E with multiple filesmultilib select %qs is invalidmultilib exclusion %qs is invalid%s: %s compiler not installed on this systemrecompiling with -fcompare-debugduring -fcompare-debug recompilation%s: could not determine length of compare-debug file %s%s: -fcompare-debug failure (length)%s: could not open compare-debug file %sgcc driver version %s %sexecuting gcc version %s -fuse-linker-plugin, but %s not found Linker options ============== Use "-Wl,OPTION" to pass "OPTION" to the linker. %s: linker input file unused because linking not donefailed to get process times: %m%s signal terminated program %swrong number of arguments to %%:debug-level-gttoo few arguments to %%:compare-debug-auxbase-opttoo many arguments to %%:compare-debug-auxbase-optargument to %%:compare-debug-auxbase-opt does not end in .gktoo few arguments to %%:replace-extensionAssembler options ================= Use "-Wa,OPTION" to pass "OPTION" to the assembler. ^([1-9][0-9]*|0)(\.([1-9][0-9]*|0))*$too few arguments to %%:version-comparetoo many arguments to %%:version-compareunknown operator %qs in %%:version-compare -pass-exit-codes Exit with highest error code from a phase. --help Display this information. --target-help Display target specific command line options. --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...]. Display specific types of command line options. (Use '-v --help' to display command line options of sub-processes). --version Display compiler version information. -dumpspecs Display all of the built in spec strings. -dumpversion Display the version of the compiler. -dumpmachine Display the compiler's target processor. -print-search-dirs Display the directories in the compiler's search path. -print-libgcc-file-name Display the name of the compiler's companion library. -print-file-name= Display the full path to library . -print-prog-name= Display the full path to compiler component . -print-multiarch Display the target's normalized GNU triplet, used as a component in the library path. -print-multi-directory Display the root directory for versions of libgcc. -print-multi-lib Display the mapping between command line options and multiple library search directories. -print-multi-os-directory Display the relative path to OS libraries. -print-sysroot Display the target libraries directory. -print-sysroot-headers-suffix Display the sysroot suffix used to find headers. -Wa, Pass comma-separated on to the assembler. -Wp, Pass comma-separated on to the preprocessor. -Wl, Pass comma-separated on to the linker. -Xassembler Pass on to the assembler. -Xpreprocessor Pass on to the preprocessor. -Xlinker Pass on to the linker. -save-temps Do not delete intermediate files. -save-temps= Do not delete intermediate files. -no-canonical-prefixes Do not canonicalize paths when building relative prefixes to other gcc components. -pipe Use pipes rather than intermediate files. -time Time the execution of each subprocess. -specs= Override built-in specs with the contents of . -std= Assume that the input sources are for . --sysroot= Use as the root directory for headers and libraries. -B Add to the compiler's search paths. -v Display the programs invoked by the compiler. -### Like -v but options quoted and commands not executed. -E Preprocess only; do not compile, assemble or link. -S Compile only; do not assemble or link. -c Compile and assemble, but do not link. -o Place the output into . -pie Create a dynamically linked position independent executable. -shared Create a shared library. -x Specify the language of the following input files. Permissible languages include: c c++ assembler none 'none' means revert to the default behavior of guessing the language based on the file's extension. Options starting with -g, -f, -m, -O, -W, or --param are automatically passed on to the various sub-processes invoked by %s. In order to pass other options on to these processes the -W options must be used. environment variable %qs not definedrestoring saved key: %s value: %s The bug is not reproducible, so it is likely a hardware or OS problem. Preprocessed source stored into %s file, please attach this to your bugreport. %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S: %(linker) %{!fno-use-linker-plugin:%{!fno-lto: -plugin %(linker_plugin_file) -plugin-opt=%(lto_wrapper) -plugin-opt=-fresolution=%u.res %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}} }}%{flto|flto=*:% %s %s%s: optimizerstargetundocumentedjoinedtrace-pctrace-cmppointer-subtractshiftshift-baseshift-exponentinteger-divide-by-zerovla-boundsigned-integer-overflowfloat-divide-by-zerofloat-cast-overflowbounds-strictreturns-nonnull-attributevptrpointer-overflowdwarf-2%s: --param arguments should be of the form NAME=VALUEinvalid --param name %qs; did you mean %qs?--help argument %q.*s is ambiguous, please be more specificunrecognized argument to --help= option: %q.*s-Werror=%s: -%s is not an option that controls warningsgetting core file size maximum limit: %msetting core file size limit to maximum: %munrecognized gcc debugging option: %cHSA has not been enabled during configuration%<-foffload-abi%> option can be specified only for offload compilerstructure alignment must be a small power of two, not %dinvalid arguments for %<-fpatchable_function_entry%>unknown stack check parameter %qs%<-gdwarf%s%> is ambiguous; use %<-gdwarf-%s%> for DWARF version or %<-gdwarf -g%s%> for debug leveldwarf version %d is not supporteddebug format %qs conflicts with prior selectionunrecognized debug output level %qsdebug output level %qs is too highargument to %<-O%> should be a non-negative integer, %, % or %section anchors must be disabled when unit-at-a-time is disabledtoplevel reorder must be disabled when unit-at-a-time is disabledtransactional memory is not supported with non-call exceptionssection anchors must be disabled when toplevel reorder is disabled%<-freorder-blocks-and-partition%> does not work with exceptions on this architecture%<-freorder-blocks-and-partition%> does not support unwind info on this architecture%<-freorder-blocks-and-partition%> does not work on this architecture%<-fno-fat-lto-objects%> are supported only with linker plugin%<-gsplit-dwarf%> is not supported with LTO, disabling%<-fsplit-stack%> is not supported by this compiler configuration%<-fsanitize=pointer-compare%> must be combined with %<-fsanitize=address%> or %<-fsanitize=kernel-address%>%<-fsanitize=pointer-subtract%> must be combined with %<-fsanitize=address%> or %<-fsanitize=kernel-address%>%<-fsanitize=address%> is incompatible with %<-fsanitize=kernel-address%>%<-fsanitize=address%> and %<-fsanitize=kernel-address%> are incompatible with %<-fsanitize=thread%>%<-fsanitize=leak%> is incompatible with %<-fsanitize=thread%>%<-fsanitize-recover=%s%> is not supported%<-fsanitize-address-use-after-scope%> requires %<-fstack-reuse=none%> optiontransactional memory is not supported with %<-fsanitize=address%>transactional memory is not supported with %<-fsanitize=kernel-address%>live patching is not supported with LTO%<-fipa-cp-clone%> is incompatible with %<-flive-patching=inline-only-static%>%<-fipa-sra%> is incompatible with %<-flive-patching=inline-only-static%>%<-fpartial-inlining%> is incompatible with %<-flive-patching=inline-only-static%>%<-fipa-cp%> is incompatible with %<-flive-patching=inline-only-static%>%<-fwhole-program%> is incompatible with %<-flive-patching=inline-only-static|inline-clone%>%<-fipa-pta%> is incompatible with %<-flive-patching=inline-only-static|inline-clone%>%<-fipa-reference%> is incompatible with %<-flive-patching=inline-only-static|inline-clone%>%<-fipa-ra%> is incompatible with %<-flive-patching=inline-only-static|inline-clone%>%<-fipa-icf%> is incompatible with %<-flive-patching=inline-only-static|inline-clone%>%<-fipa-icf-functions%> is incompatible with %<-flive-patching=inline-only-static|inline-clone%>%<-fipa-icf-variables%> is incompatible with %<-flive-patching=inline-only-static|inline-clone%>%<-fipa-bit-cp%> is incompatible with %<-flive-patching=inline-only-static|inline-clone%>%<-fipa-vrp%> is incompatible with %<-flive-patching=inline-only-static|inline-clone%>%<-fipa-pure-const%> is incompatible with %<-flive-patching=inline-only-static|inline-clone%>-falign-loops=%d is not between 0 and %d-falign-jumps=%d is not between 0 and %d-falign-functions=%d is not between 0 and %d-falign-labels=%d is not between 0 and %ddefault %d minimum %d maximum %dSame as %s. Use the latter option instead. No options with the desired characteristics were found None found. Use --help=%s to show *all* the options supported by the %s front-end. All options with the desired characteristics have already been displayed The following options are target specificThe following options control compiler warning messagesThe following options control optimizationsThe following options are language-independentThe --param option recognizes the following as parametersThe following options are specific to just the language The following options are supported by the language The following options are not documentedThe following options take separate argumentsThe following options take joined argumentsunrecognized include_flags 0x%x passed to print_specific_helpThe following options are language-relatedargument %qs to %<-femit-struct-debug-detailed%> not recognizedargument %qs to %<-femit-struct-debug-detailed%> unknown%<-femit-struct-debug-detailed=dir:...%> must allow at least as much as %<-femit-struct-debug-detailed=ind:...%>%<-fsanitize=all%> option is not validunrecognized argument to -f%ssanitize%s= option: %q.*s; did you mean %qs?unrecognized argument to -f%ssanitize%s= option: %q.*s%<%s%> attribute directive ignoredttttt&Y jayset_Wstrict_aliasingprint_specific_helpcommon_handle_optioncontrol_options_for_live_patchingmaybe_default_optioninit_options_structtarget_handle_option_B;!%&'D?)"<49>A8ZiDcEpH37BceC`d '*+!{ R&2=`5n Uses of this option are diagnosed.This option lacks documentation.sysbaseanynonegen:ord:ind:dir:dfn:../../gcc/opts-common.c-Werror=-Wno--W-fno--f-gno--g-mno---debug=--machine---machine-no---machine=--machine=no---machine--optimize=-O--std=--std--warn---warn-no-----no-command line option %qs is not supported by this configurationargument to %qs should be a non-negative integerargument to %qs is not between %d and %dunrecognized argument in option %qsvalid arguments to %qs are: %s; did you mean %qs?valid arguments to %qs are: %s UM(;k3J " control_warning_optionread_cmdline_optiongenerate_optionprune_optionsgenerate_canonical_optiondecode_cmdline_optionadd_misspelling_candidatesopt_enum_arg_to_valueoptions.c-###--all-warnings--ansi--assemble--assertassertion missing after %qs--assert=--comments--comments-in-macros--compile--coverage--debug--define-macromacro name missing after %qs--define-macro=--dependencies--dump--dump=--dumpbase--dumpdir--entry--entry=--extra-warnings--for-assembler--for-assembler=--for-linker--for-linker=--force-link--force-link=Display this information.--help=--imacrosmissing filename after %qs--imacros=--include--include-barrier--include-directorymissing path after %qs--include-directory-after--include-directory-after=--include-directory=--include-prefix--include-prefix=--include-with-prefix--include-with-prefix-after--include-with-prefix-after=--include-with-prefix-before--include-with-prefix-before=--include-with-prefix=--include=--language--language=--library-directory--library-directory=--no-canonical-prefixes--no-integrated-cpp--no-line-commands--no-standard-includes--no-standard-libraries--no-sysroot-suffix--no-warnings--optimize--output--output-pch=--output=--param--param=--pass-exit-codes--pedantic--pedantic-errors--pie--pipe--prefix--prefix=--preprocess--print-file-name--print-file-name=--print-libgcc-file-name--print-multi-directory--print-multi-lib--print-multi-os-directory--print-multiarch--print-prog-name--print-prog-name=--print-search-dirs--print-sysroot--profile--save-temps--shared--specs--specs=--static--static-pie--symbolic--sysroot--sysroot=Alias for --help=target.--time--trace-includes--traditional--traditional-cpp--trigraphs--undefine-macro--undefine-macro=--user-dependencies--verbose--write-dependencies--write-user-dependencies-A-BDo not discard comments.-CC-D-H-I-J-MGenerate make dependencies.-MD-MF-MG-MM-MMD-MP-MQ-MT-N-Ofast-Og-Os-P-Q-Qn-Qy-R-S-T-Tbss-Tbss=-Tdata-Tdata=-Ttext-Ttext=-U-U Undefine .-Wa,-Wabi-Wabi-tag-Wabi=-Waddress-Waggregate-return-Waliasing-Walign-commons-Waligned-new-Waligned-new=-WallEnable most warning messages.-Walloc-size-larger-than=-Walloc-zero-WallocaWarn on any use of alloca.-Walloca-larger-than=-Wampersand-Wargument-mismatch-Warray-bounds-Warray-bounds=-Warray-temporaries-Wassign-intercept-Wattribute-alias-Wattributes-Wbad-function-cast-Wbidi-charsany-Wbidi-chars=-Wbool-compare-Wbool-operation-Wbuiltin-macro-redefined-Wc++-compat-Wc++0x-compat-Wc++11-compat-Wc++14-compat-Wc++17-compat-Wc++1z-compat-Wc-binding-type-Wc90-c99-compat-Wc99-c11-compat-Wcast-align-Wcast-align=strict-Wcast-function-type-Wcast-qual-Wcatch-value-Wcatch-value=-Wchar-subscripts-Wcharacter-truncation-Wchkp-Wclass-memaccess-Wclobbered-Wcomment-WcommentsSynonym for -Wcomment.-Wcompare-reals-Wconditionally-supported-Wconversion-Wconversion-extra-Wconversion-null-Wcoverage-mismatch-Wcpp-Wctor-dtor-privacy-Wdangling-elseWarn about dangling else.-Wdate-time-Wdeclaration-after-statement-Wdelete-incomplete-Wdelete-non-virtual-dtor-Wdeprecated-Wdeprecated-declarations-Wdesignated-init-Wdisabled-optimization-Wdiscarded-array-qualifiers-Wdiscarded-qualifiers-Wdiv-by-zero-Wdo-subscript-Wdouble-promotion-Wduplicate-decl-specifier-Wduplicated-branches-Wduplicated-cond-Weffc++-Wempty-body-Wendif-labels-Wenum-compare-WerrorTreat all warnings as errors.implicit-function-declaration-Wexpansion-to-defined-Wextra-Wextra-semi-Wfatal-errors-Wfloat-conversion-Wfloat-equal-Wformat-Wformat-contains-nul-Wformat-extra-args-Wformat-nonliteral-Wformat-overflow-Wformat-overflow=-Wformat-security-Wformat-signedness-Wformat-truncation-Wformat-truncation=-Wformat-y2k-Wformat-zero-length-Wformat=-Wframe-address-Wframe-larger-than=-Wfree-nonheap-object-Wfrontend-loop-interchange-Wfunction-elimination-Whsa-Wif-not-aligned-Wignored-attributes-Wignored-qualifiers-Wimplicit-Wimplicit-fallthrough-Wimplicit-fallthrough=-Wimplicit-int-Wimplicit-interface-Wimplicit-procedure-Wimport-Wincompatible-pointer-types-Winherited-variadic-ctor-Winit-self-Winline-Wint-conversion-Wint-in-bool-context-Wint-to-pointer-cast-Winteger-division-Wintrinsic-shadow-Wintrinsics-std-Winvalid-memory-model-Winvalid-offsetof-Winvalid-pch-Wjump-misses-init-Wl,-Wlarger-than--Wlarger-than=-Wline-truncation-Wliteral-suffix-Wlogical-not-parentheses-Wlogical-op-Wlong-long-Wlto-type-mismatch-Wmain-Wmaybe-uninitialized-Wmemset-elt-size-Wmemset-transposed-args-Wmisleading-indentation-Wmissing-attributes-Wmissing-braces-Wmissing-declarations-Wmissing-field-initializers-Wmissing-format-attribute-Wmissing-include-dirs-Wmissing-noreturn-Wmissing-parameter-type-Wmissing-prototypes-Wmudflap-Wmultichar-Wmultiple-inheritance-Wmultistatement-macros-WnamespacesWarn on namespace definition.-Wnarrowing-Wnested-externs-Wnoexcept-Wnoexcept-type-Wnon-template-friend-Wnon-virtual-dtor-Wnonnull-Wnonnull-compare-Wnormalizednfc-Wnormalized=-Wnull-dereference-Wodr-Wold-style-cast-Wold-style-declaration-Wold-style-definition-Wopenmp-simd-Woverflow-Woverlength-strings-Woverloaded-virtual-Woverride-init-Woverride-init-side-effects-Wp,-Wpacked-Wpacked-bitfield-compat-Wpacked-not-aligned-Wpadded-Wparentheses-Wpedantic-Wplacement-new-Wplacement-new=-Wpmf-conversions-Wpointer-arith-Wpointer-compare-Wpointer-sign-Wpointer-to-int-cast-Wpragmas-Wproperty-assign-default-Wprotocol-Wpsabi-Wreal-q-constant-Wrealloc-lhs-Wrealloc-lhs-all-Wredundant-decls-Wregister-Wreorder-Wrestrict-Wreturn-local-addr-Wreturn-type-Wscalar-storage-order-Wselector-Wsequence-point-Wshadow-Wshadow-compatible-local-Wshadow-ivar-Wshadow-local-Wshadow=compatible-local-Wshadow=global-Wshadow=local-Wshift-count-negative-Wshift-count-overflow-Wshift-negative-value-Wshift-overflow-Wshift-overflow=-Wsign-compare-Wsign-conversion-Wsign-promo-Wsized-deallocation-Wsizeof-array-argument-Wsizeof-pointer-div-Wsizeof-pointer-memaccess-Wstack-protector-Wstack-usage=-Wstrict-aliasing-Wstrict-aliasing=-Wstrict-null-sentinel-Wstrict-overflow-Wstrict-overflow=-Wstrict-prototypes-Wstrict-selector-match-Wstringop-overflow-Wstringop-overflow=-Wstringop-truncation-Wsubobject-linkage-Wsuggest-attribute=cold-Wsuggest-attribute=const-Wsuggest-attribute=format-Wsuggest-attribute=malloc-Wsuggest-attribute=noreturn-Wsuggest-attribute=pure-Wsuggest-final-methods-Wsuggest-final-types-Wsuggest-override-Wsurprising-Wswitch-Wswitch-bool-Wswitch-default-Wswitch-enum-Wswitch-unreachable-Wsync-nand-Wsynth-Wsystem-headers-Wtabs-Wtarget-lifetime-Wtautological-compare-Wtemplates-Wterminate-Wtraditional-Wtraditional-conversion-Wtrampolines-Wtrigraphs-Wtype-limits-Wundeclared-selector-Wundef-Wundefined-do-loop-Wunderflow-Wuninitialized-Wunknown-pragmas-Wunreachable-code-Wunsafe-loop-optimizations-Wunsuffixed-float-constants-Wunused-Wunused-but-set-parameter-Wunused-but-set-variable-Wunused-const-variable-Wunused-const-variable=-Wunused-dummy-argument-Wunused-function-Wunused-labelWarn when a label is unused.-Wunused-local-typedefs-Wunused-macros-Wunused-parameter-Wunused-result-Wunused-value-Wunused-variable-Wuse-without-only-Wuseless-castWarn about useless casts.-Wvarargs-Wvariadic-macros-Wvirtual-inheritance-Wvirtual-move-assign-Wvla-Wvla-larger-than=-Wvolatile-register-var-Wwrite-strings-Wzerotrip-Xassembler-Xlinker-Xpreprocessor-Z-aux-info-aux-info=-auxbase-auxbase-strip-cEnable preprocessing.-cpp=-d-dumpfullversion-dumpmachine-dumpspecs-dumpversion-e-export-dynamic-fPIC-fPIE-fRTS=Select the runtime.-fabi-compat-version=-fabi-version=-faccess-control-fada-spec-parent=-falign-commons-falign-functionsAlign the start of functions.-falign-functions=-falign-jumps-falign-jumps=-falign-labelsAlign all labels.-falign-labels=-falign-loopsAlign the start of loops.-falign-loops=-faligned-new-faligned-new=-fall-intrinsics-fall-virtual-fallow-leading-underscore-falt-external-templatesNo longer supported.-fargument-alias-fargument-noalias-fargument-noalias-anything-fargument-noalias-global-fasan-shadow-offset=-fasmRecognize the "asm" keyword.-fassociative-math-fasynchronous-unwind-tables-fauto-inc-dec-fauto-profile-fauto-profile=-fautomatic-fbackslash-fbacktrace-fblas-matmul-limit=-fbounds-check-fbranch-count-reg-fbranch-probabilities-fbranch-target-load-optimize-fbtr-bb-exclusive-fbuilding-libgcc-fbuiltinRecognize built-in functions.-fbuiltin--fbuiltin-printfIgnored.-fc-prototypes-fcall-saved--fcall-used--fcaller-saves-fcanonical-system-headers-fcf-protectionfull-fcf-protection=-fcheck-array-temporaries-fcheck-data-deps-fcheck-new-fcheck-pointer-bounds-fcheck=-fchecking-fchecking=-fchkp-check-incomplete-type-fchkp-check-read-fchkp-check-write-fchkp-instrument-calls-fchkp-instrument-marked-only-fchkp-narrow-bounds-fchkp-optimize-fchkp-store-bounds-fchkp-use-static-bounds-fchkp-use-wrappers-fcilkplus-fcoarray=-fcode-hoistingEnable code hoisting.-fcombine-stack-adjustments-fcommon-fcompare-debug-fcompare-debug-second-fcompare-elim-fconcepts-fcond-mismatch-fconserve-space-fconserve-stack-fconstant-string-class=-fconstexpr-depth=-fconstexpr-loop-limit=-fconvert=-fcprop-registers-fcray-pointer-fcrossjumping-fcse-follow-jumps-fcse-skip-blocks-fcx-fortran-rules-fcx-limited-range-fd-lines-as-code-fd-lines-as-comments-fdata-sections-fdbg-cnt-list-fdbg-cnt=-fdce-fdebug-cpp-fdebug-prefix-map=-fdebug-types-section-fdec-fdec-intrinsic-ints-fdec-math-fdec-static-fdec-structure-fdeclone-ctor-dtor-fdeduce-init-list-fdefault-double-8-fdefault-inline-fdefault-integer-8-fdefault-real-10-fdefault-real-16-fdefault-real-8-fdefer-pop-fdelayed-branch-fdelete-dead-exceptions-fdelete-null-pointer-checks-fdevirtualize-fdevirtualize-at-ltrans-fdevirtualize-speculatively-fdiagnostics-colornever-fdiagnostics-color=-fdiagnostics-generate-patch-fdiagnostics-show-caret-fdiagnostics-show-location=-fdiagnostics-show-option-fdirectives-onlyPreprocess directives only.-fdisable--fdollar-ok-fdollars-in-identifiers-fdse-fdump--fdump-ada-spec-fdump-ada-spec-slim-fdump-core-fdump-final-insns-fdump-fortran-optimized-fdump-fortran-original-fdump-go-spec=-fdump-internal-locations-fdump-parse-tree-fdump-passesDump optimization passes.-fdump-unnumbered-fdump-unnumbered-links-fdwarf2-cfi-asm-fearly-inliningPerform early inlining.-felide-constructors-felide-type-feliminate-dwarf2-dups-femit-class-debug-always-femit-struct-debug-baseonly-femit-struct-debug-detailed=-femit-struct-debug-reduced-fenable--fenforce-eh-specs-fenum-int-equiv-fexceptionsEnable exception handling.-fexcess-precision=-fexec-charset=-fexpensive-optimizations-fext-numeric-literals-fextended-identifiers-fextern-tls-init-fexternal-blas-fexternal-templates-ff2cUse f2c calling convention.-ffast-math-ffat-lto-objects-ffile-prefix-map=-ffinite-math-only-ffixed--ffixed-form-ffixed-line-length--ffixed-line-length-none-ffloat-store-ffor-scope-fforce-addr-fforward-propagate-ffp-contract=-ffp-int-builtin-inexact-ffpe-summary=-ffpe-trap=-ffree-form-ffree-line-length--ffree-line-length-none-ffreestanding-ffriend-injection-ffrontend-loop-interchange-ffrontend-optimize-ffunction-cse-ffunction-sections-fgcse-fgcse-after-reload-fgcse-las-fgcse-lm-fgcse-sm-fgimpleEnable parsing GIMPLE.-fgnat-encodings=-fgnu-keywords-fgnu-runtime-fgnu-tm-fgnu-unique-fgnu89-inline-fgo-c-header=-fgo-check-divide-overflow-fgo-check-divide-zero-fgo-compiling-runtime-fgo-debug-escape-fgo-debug-escape-hash=-fgo-dump--fgo-optimize--fgo-pkgpath=-fgo-prefix=-fgo-relative-import-path=-fgraphite-fgraphite-identity-fguess-branch-probability-fguiding-decls-fhandle-exceptions-fhelp-fhelp=-fhoist-adjacent-loads-fhonor-std-fhosted-fhuge-objects-fidentProcess #ident directives.-fif-conversion-fif-conversion2-fimplement-inlines-fimplicit-inline-templates-fimplicit-none-fimplicit-templates-findirect-inliningPerform indirect inlining.-finhibit-size-directive-finit-character=-finit-derived-finit-integer=-finit-local-zero-finit-logical=-finit-real=-finline-finline-atomics-finline-functions-finline-limit--finline-limit=-finline-matmul-limit=-finline-small-functions-finput-charset=-finstrument-functions-finteger-4-integer-8-fintrinsic-modules-path-fintrinsic-modules-path=-fipa-bit-cp-fipa-cp-fipa-cp-alignment-fipa-cp-clone-fipa-icf-fipa-icf-functions-fipa-icf-variables-fipa-matrix-reorg-fipa-profile-fipa-pta-fipa-pure-const-fipa-ra-fipa-reference-fipa-sra-fipa-struct-reorg-fipa-vrp-fira-algorithm=-fira-hoist-pressure-fira-loop-pressure-fira-region=-fira-share-save-slots-fira-share-spill-slots-fira-verbose=-fivar-visibility=-fivopts-fjump-tables-fkeep-gc-roots-live-fkeep-inline-dllexport-fkeep-inline-functions-fkeep-static-consts-fkeep-static-functions-flabels-ok-flax-vector-conversions-fleading-underscore-flifetime-dse-flifetime-dse=-flimit-function-alignment-flinker-output=-flive-patchinginline-clone-flive-patching=-flive-range-shrinkage-flocal-ivars-floop-block-floop-flatten-floop-interchange-floop-nest-optimize-floop-optimize-floop-parallelize-allMark all loops as parallel.-floop-strip-mine-floop-unroll-and-jam-flra-remat-flto-flto-compression-level=-flto-odr-type-merging-flto-partition=-flto-report-flto-report-wpa-flto=-fltrans-fltrans-output-list=-fmacro-prefix-map=-fmath-errno-fmax-array-constructor=-fmax-errors=-fmax-identifier-length=-fmax-stack-var-size=-fmax-subrecord-length=-fmem-report-fmem-report-wpa-fmerge-all-constants-fmerge-constants-fmerge-debug-strings-fmessage-length=-fmodule-private-fmodulo-sched-fmodulo-sched-allow-regmoves-fmove-loop-invariants-fms-extensions-fmudflap-fmudflapir-fmudflapth-fname-mangling-version--fnew-abi-fnew-inheriting-ctors-fnew-ttp-matching-fnext-runtime-fnil-receivers-fnon-call-exceptions-fnonansi-builtins-fnonnull-objects-fnothrow-opt-fobjc-abi-version=-fobjc-call-cxx-cdtors-fobjc-direct-dispatch-fobjc-exceptions-fobjc-gc-fobjc-nilcheck-fobjc-sjlj-exceptions-fobjc-std=objc1-foffload-abi=-foffload=-fomit-frame-pointer-fopenaccEnable OpenACC.-fopenacc-dim=-fopenmp-fopenmp-simd-foperator-names-fopt-info-fopt-info--foptimize-register-move-foptimize-sibling-calls-foptimize-strlen-foptional-diags-fpack-derived-fpack-struct-fpack-struct=-fpartial-inliningPerform partial inlining.-fpatchable-function-entry=-fpcc-struct-return-fpch-deps-fpch-preprocess-fpeel-loopsPerform loop peeling.-fpeephole-fpeephole2-fpermissive-fpermitted-flt-eval-methods=-fpic-fpie-fplan9-extensions-fplt-fplugin-arg--fplugin=Specify a plugin to load.-fpost-ipa-mem-report-fpre-ipa-mem-report-fpredictive-commoning-fprefetch-loop-arrays-fpreprocessed-fpretty-templates-fprintf-return-value-fprofile-fprofile-abs-path-fprofile-arcs-fprofile-correction-fprofile-dir=-fprofile-generate-fprofile-generate=-fprofile-reorder-functions-fprofile-report-fprofile-update=-fprofile-use-fprofile-use=-fprofile-values-fprotect-parens-frandom-seed-frandom-seed=-frange-check-freal-4-real-10-freal-4-real-16-freal-4-real-8-freal-8-real-10-freal-8-real-16-freal-8-real-4-frealloc-lhs-freciprocal-math-frecord-gcc-switches-frecord-marker=4-frecord-marker=8-frecursive-free-freg-struct-return-fregmove-frename-registers-freorder-blocks-freorder-blocks-algorithm=-freorder-functions-frepack-arrays-freplace-objc-classes-frepo-freport-bug-frequire-return-statement-frerun-cse-after-loop-frerun-loop-opt-fresolution=The resolution file.-frounding-math-frtti-fsanitize-coverage=-fsanitize-recover-fsanitize-recover=-fsanitize-sections=-fsanitize=Select what to sanitize.-fsched-dep-count-heuristic-fsched-group-heuristic-fsched-interblock-fsched-last-insn-heuristic-fsched-pressure-fsched-rank-heuristic-fsched-spec-fsched-spec-insn-heuristic-fsched-spec-load-fsched-spec-load-dangerous-fsched-stalled-insns-fsched-stalled-insns-dep-fsched-stalled-insns-dep=-fsched-stalled-insns=-fsched-verbose=-fsched2-use-superblocks-fsched2-use-traces-fschedule-fusion-fschedule-insns-fschedule-insns2-fsecond-underscore-fsection-anchors-fsee-fsel-sched-pipelining-fselective-scheduling-fselective-scheduling2-fself-test=-fsemantic-interposition-fshort-enums-fshort-wchar-fshow-column-fshrink-wrap-fshrink-wrap-separate-fsign-zero-fsignaling-nans-fsigned-bitfields-fsigned-char-fsigned-zeros-fsimd-cost-model=-fsingle-precision-constant-fsized-deallocation-fsplit-ivs-in-unroller-fsplit-loopsPerform loop splitting.-fsplit-paths-fsplit-stack-fsplit-wide-types-fsquangle-fssa-backprop-fssa-phiopt-fsso-struct=-fstack-arrays-fstack-check-fstack-check=-fstack-clash-protection-fstack-limit-fstack-limit-register=-fstack-limit-symbol=-fstack-protector-fstack-protector-all-fstack-protector-explicit-fstack-protector-strong-fstack-reuse=-fstack-usage-fstats-fstdarg-opt-fstore-mergingMerge adjacent stores.-fstrength-reduce-fstrict-aliasing-fstrict-enums-fstrict-overflow-fstrict-prototype-fstrict-volatile-bitfields-fstrong-eval-order-fstrong-eval-order=-fsync-libcalls-fsyntax-only-ftabstop=-ftail-call-workaround-ftail-call-workaround=-ftarget-help-ftemplate-backtrace-limit=-ftemplate-depth--ftemplate-depth=-ftest-coverage-ftest-forall-temp-fthis-is-variable-fthread-jumps-fthreadsafe-statics-ftime-report-details-ftls-model=-ftoplevel-reorder-ftracer-ftrack-macro-expansion-ftrack-macro-expansion=-ftrampolines-ftrapping-math-ftrapv-ftree-bit-ccp-ftree-builtin-call-dce-ftree-ccp-ftree-ch-ftree-coalesce-inlined-vars-ftree-coalesce-vars-ftree-copy-prop-ftree-copyrename-ftree-cselim-ftree-dce-ftree-dominator-opts-ftree-dse-ftree-forwprop-ftree-fre-ftree-loop-distribution-ftree-loop-if-convert-ftree-loop-if-convert-stores-ftree-loop-im-ftree-loop-ivcanon-ftree-loop-linear-ftree-loop-optimize-ftree-loop-vectorize-ftree-lrs-ftree-parallelize-loops=-ftree-partial-pre-ftree-phiprop-ftree-pre-ftree-pta-ftree-reassoc-ftree-salias-ftree-scev-cprop-ftree-sink-ftree-slp-vectorize-ftree-slsr-ftree-sra-ftree-store-ccp-ftree-store-copy-prop-ftree-switch-conversion-ftree-tail-mergeEnable tail merging on trees.-ftree-ter-ftree-vect-loop-version-ftree-vectorize-ftree-vectorizer-verbose=-ftree-vrp-funconstrained-commons-funderscoring-funit-at-a-time-funroll-all-loops-funroll-loops-funsafe-loop-optimizations-funsafe-math-optimizations-funsigned-bitfields-funsigned-char-funswitch-loopsPerform loop unswitching.-funwind-tables-fuse-cxa-atexit-fuse-cxa-get-exception-ptr-fuse-ld=bfd-fuse-ld=gold-fuse-ld=lld-fuse-linker-plugin-fvar-trackingPerform variable tracking.-fvar-tracking-assignments-fvar-tracking-uninit-fvect-cost-modelunlimited-fvect-cost-model=-fverbose-asm-fversion-fvisibility-inlines-hidden-fvisibility-ms-compat-fvisibility=-fvpt-fvtable-gc-fvtable-thunks-fvtable-verify=-fvtv-counts-fvtv-debug-fweak-fweb-fwhole-file-fwhole-program-fwide-exec-charset=-fworking-directory-fwpa-fwpa=-fwrapv-fwrapv-pointer-fxref-fzee-fzero-initialized-in-bss-fzero-link-gantCatch typos.-gas-loc-support-gas-locview-support-gcoff-gcoff1-gcoff2-gcoff3-gcolumn-info-gdwarf-gdwarf--gen-decls-ggdb-ggnu-pubnames-ginline-points-gnat-gnatO-gno-pubnames-gpubnames-grecord-gcc-switches-gsplit-dwarf-gstabs-gstabs+-gstatement-frontiers-gstrict-dwarf-gvariable-location-views-gvms-gxcoff-gxcoff+-gz-gz=-h-idirafter-iquote-iwithprefix-iwithprefixbefore-k8Synonym of -gnatk8.-lang-asm-m128bit-long-doublesizeof(long double) is 16.-m16Generate 16bit i386 code.-m32Generate 32bit i386 code.-m3dnowa-m64Generate 64bit x86-64 code.-m80387Use hardware fp.-m8bit-idiv-m96bit-long-doublesizeof(long double) is 12.-mabi=-maccumulate-outgoing-args-maddress-mode=Use given address mode.-malign-data=Use the given data alignment.-malign-double-malign-functions=-malign-jumps=-malign-loops=-malign-stringops-mandroid-march=Generate code for given CPU.-masm=Use given assembler dialect.-mavx256-split-unaligned-load-mbionicUse Bionic C library.-mbranch-cost=-mcall-ms2sysv-xlogues-mcet-switch-mcldSupport CLWB instruction.-mcmodel=Use given x86-64 code model.-mcpu=-mcrc32-mdispatch-scheduler-mdump-tune-features-mfancy-math-387-mfentry-mforce-drap-mforce-indirect-call-mfp-ret-in-387-mfpmath=-mfunction-return=-mfused-madd-mgeneral-regs-only-mglibcUse GNU C library.-mhard-float-mharden-sls=-miamcu-mieee-fp-mincoming-stack-boundary=-mindirect-branch-cs-prefix-mindirect-branch-register-mindirect-branch=-minline-all-stringops-mintel-syntaxintelatt-mlarge-data-threshold=-mlong-double-128Use 128-bit long double.-mlong-double-64Use 64-bit long double.-mlong-double-80Use 80-bit long double.-mmemcpy-strategy=-mmemset-strategy=-mmitigate-rop-mmpxSupport MPX code generation.-mms-bitfields-mmuslUse musl C library.-mno-align-stringops-mno-defaultClear all tune features.-mno-fancy-math-387-mno-push-args-mno-red-zone-mno-sse4-mnop-mcount-momit-leaf-frame-pointer-mpc32-mpc64-mpc80-mpcommit%<-mpcommit%> was deprecated-mprefer-avx128256-mprefer-vector-width=-mpreferred-stack-boundary=-mpush-argsSupport RDSEED instruction.-mrecip-mrecip=-mrecord-mcount-mred-zone-mregparm=-mrtdAlternate calling convention.-mskip-rax-setup-msoft-floatDo not use hardware fp.-msse2avx-msse4-msse5%<-msse5%> was removed-msseregparm-mstack-arg-probeEnable stack probing.-mstack-protector-guard-reg=-mstack-protector-guard=-mstackrealignRealign stack in prologue.-mstringop-strategy=-mstv-mtls-dialect=-mtls-direct-seg-refs-mtune-ctrl=-mtune=Schedule code for given CPU.-muclibcUse uClibc C library.-mveclibabi=Vector library ABI to use.-mvect8-ret-in-mem-mvzeroupper-mx32Generate 32bit x86-64 code.Support XSAVEC instructions.Support XSAVEOPT instruction.-n-no-pie-nocppDisable preprocessing.-nodefaultlibs-nostartfiles-nostdinc-nostdinc++-nostdlib-pEnable function profiling.-pg-posix-print-objc-runtime-info-print-sysroot-headers-suffix-pthread-r-rdynamic-remap-s-save-temps=Create a shared library.-shared-libgcc-static-libasan-static-libgcc-static-libgfortran-static-libgo-static-liblsan-static-libmpx-static-libmpxwrappers-static-libstdc++-static-libtsan-static-libubsan-std=c++03-std=c++0x-std=c++11-std=c++14-std=c++17-std=c++1y-std=c++1z-std=c++2a-std=c++98-std=c11-std=c17-std=c18-std=c1x-std=c89-std=c90-std=c99-std=c9x-std=f2003-std=f2008-std=f2008ts-std=f2018-std=f95-std=gnu-std=gnu++03-std=gnu++0x-std=gnu++11-std=gnu++14-std=gnu++17-std=gnu++1y-std=gnu++1z-std=gnu++2a-std=gnu++98-std=gnu11-std=gnu17-std=gnu18-std=gnu1x-std=gnu89-std=gnu90-std=gnu99-std=gnu9x-std=iso9899:1990-std=iso9899:199409-std=iso9899:1999-std=iso9899:199x-std=iso9899:2011-std=iso9899:2017-std=iso9899:2018-std=legacy-t-time=-tno-android-cc-tno-android-ld-u-undef-vEnable verbose output.-wSuppress warnings.-x-zAdaSCILAdaWhyBRIGLTOObjCObjC++Valid arguments to -mfpmath=:Unrecognized option: %qsunknown IRA algorithm %qsunknown IRA region %qsunknown linker output %qsunknown offload ABI %qsunknown Stack Reuse Level %qsunknown TLS model %qspreinitcheapglobal-dynamicinitial-execlocal-dynamiclocal-execgnu2internalprotectedsomebyte_looplibcallrep_4byterep_8byterep_byteunrolled_loopvector_loopnamed_varstlsbig-endianlittle-endiannativesimplestcprefer-atomicts-18661-3ilp32lp641to1balancedmaxdynrelunknowninline-only-staticacmlsvmlcachelinepackagepublicmixedCBprioritykeepthunkthunk-externthunk-inlineindirect-jmp-infsnanswap387+sse387,ssebothsse+387sse,387standardminimalevery-lineoncenfkcunpairedzlibzlib-gnukernellargemediumsmallsysvcommon_handle_option_auto  H +--help= Display descriptions of a specific class of options. is one or more of optimizers, target, warnings, undocumented, params.--param = Set parameter to value. See below for a complete list of parameters.--print-missing-file-dependencies--print-sysroot-headers-suffix-A= Assert the to . Putting '-' before disables the to .Do not discard comments in macro expansions.-D[=] Define a with as its value. If just is given, is taken to be 1.-F Add to the end of the main framework include path.Print the name of header files as they are used.-I Add to the end of the main include path.-J Put MODULE files in 'directory'.Generate make dependencies and compile.-MF Write dependency output to the given file.Treat missing header files as generated files.Like -M but ignore system header files.Like -MD but ignore system header files.Generate phony targets for all headers.-MQ Add a MAKE-quoted target.missing makefile target after %qs-MT Add an unquoted target.-O Set optimization level to .Optimize for speed disregarding exact standards compliance.Optimize for debugging experience rather than speed or size.Optimize for space rather than speed.Do not generate #line directives.This switch is deprecated; use -Wextra instead.Warn about things that will change when compiling with an ABI-compliant compiler.Warn if a subobject has an abi_tag attribute that the complete object type does not have.Warn about things that change between the current -fabi-version and the specified version.Warn about suspicious uses of memory addresses.Warn about returning structures, unions or arrays.-Waggressive-loop-optimizationsWarn if a loop with constant number of iterations triggers undefined behavior.Warn about possible aliasing of dummy arguments.Warn about alignment of COMMON blocks.Warn about 'new' of type with extended alignment without -faligned-new.-Waligned-new=[none|global|all] Warn even if 'new' uses a class member allocation function.-Walloc-size-larger-than= Warn for calls to allocation functions that attempt to allocate objects larger than the specified number of bytes.-Walloc-zero Warn for calls to allocation functions that specify zero bytes.-Walloca-larger-than= Warn on unbounded uses of alloca, and on bounded uses of alloca whose bound can be larger than bytes.Warn about missing ampersand in continued character constants.Warn about type and rank mismatches between arguments and parameters.Warn if an array is accessed out of bounds.Warn about creation of array temporaries.Warn whenever an Objective-C assignment is being intercepted by the garbage collector.Warn about type safety and similar errors in attribute alias and related.Warn about inappropriate attribute usage.Warn about casting functions to incompatible types.-Wbidi-chars=[none|unpaired|any] Warn about UTF-8 bidirectional control characters.Warn about boolean expression compared with an integer value different from true/false.Warn about certain operations on boolean expressions.-Wbuiltin-declaration-mismatchWarn when a built-in function is declared with the wrong signature.Warn when a built-in preprocessor macro is undefined or redefined.Warn about C constructs that are not in the common subset of C and C++.Warn about C++ constructs whose meaning differs between ISO C++ 1998 and ISO C++ 2011.Warn about C++ constructs whose meaning differs between ISO C++ 2011 and ISO C++ 2014.Warn about C++ constructs whose meaning differs between ISO C++ 2014 and ISO C++ 2017.Warn if the type of a variable might be not interoperable with C.Warn about features not present in ISO C90, but present in ISO C99.Warn about features not present in ISO C99, but present in ISO C11.Warn about pointer casts which increase alignment.Warn about casts between incompatible function types.Warn about casts which discard qualifiers.Warn about catch handlers of non-reference type.Warn about subscripts whose type is "char".Warn about truncated character expressions.Warn about memory access errors found by Pointer Bounds Checker.Warn for unsafe raw memory writes to objects of class types.Warn about variables that might be changed by "longjmp" or "vfork".Warn about possibly nested block comments, and C++ comments spanning more than one physical line.Warn about equality comparisons involving REAL or COMPLEX expressions.Warn for conditionally-supported constructs.Warn for implicit type conversions that may change a value.Warn about most implicit conversions.Warn for converting NULL from/to a non-pointer type.Warn in case profiles in -fprofile-use do not match.Warn when a #warning directive is encountered.Warn when all constructors and destructors are private.Warn about __TIME__, __DATE__ and __TIMESTAMP__ usage.Warn when a declaration is found after a statement.Warn when deleting a pointer to incomplete type.Warn about deleting polymorphic objects with non-virtual destructors.Warn if a deprecated compiler feature, class, method, or field is used.Warn about uses of __attribute__((deprecated)) declarations.Warn about positional initialization of structs requiring designated initializers.Warn when an optimization pass is disabled.Warn if qualifiers on arrays which are pointer targets are discarded.Warn if type qualifiers on pointers are discarded.Warn about compile-time integer division by zero.Warn about possibly incorrect subscripts in do loops.Warn about implicit conversions from "float" to "double".Warn when a declaration has duplicate const, volatile, restrict or _Atomic specifier.Warn about duplicated branches in if-else statements.Warn about duplicated conditions in an if-else-if chain.Warn about violations of Effective C++ style rules.Warn about an empty body in an if or else statement.Warn about stray tokens after #else and #endif.Warn about comparison of different enum types.-Werror-implicit-function-declarationThis switch is deprecated; use -Werror=implicit-function-declaration instead.Treat specified warning as error.Warn if "defined" is used outside #if.Print extra (possibly unwanted) warnings.Warn about semicolon after in-class function definition.Exit on the first error occurred.Warn for implicit type conversions that cause loss of floating point precision.Warn if testing floating point numbers for equality.Warn about printf/scanf/strftime/strfmon format string anomalies.Warn about format strings that contain NUL bytes.Warn if passing too many arguments to a function for its format string.Warn about format strings that are not literals.Warn about function calls with format strings that write past the end of the destination region. Same as -Wformat-overflow=1.Warn about function calls with format strings that write past the end of the destination region.Warn about possible security problems with format functions.Warn about sign differences with format functions.Warn about calls to snprintf and similar functions that truncate output. Same as -Wformat-truncation=1.Warn about calls to snprintf and similar functions that truncate output.Warn about strftime formats yielding 2-digit years.Warn about zero-length formats.Warn when __builtin_frame_address or __builtin_return_address is used unsafely.-Wframe-larger-than= Warn if a function's stack frame requires more than bytes.Warn when attempting to free a non-heap object.Warn if loops have been interchanged.Warn about function call elimination.Warn when a function cannot be expanded to HSAIL.Warn when the field in a struct is not aligned.Warn whenever attributes are ignored.Warn whenever type qualifiers are ignored.Warn about implicit declarations.Warn when a switch case falls through.-Wimplicit-function-declarationWarn about implicit function declarations.Warn when a declaration does not specify a type.Warn about calls with implicit interface.Warn about called procedures not explicitly declared.Warn when there is a conversion between pointers that have incompatible types.Warn about C++11 inheriting constructors when the base has a variadic constructor.Warn about variables which are initialized to themselves.Warn when an inlined function cannot be inlined.Warn about incompatible integer to pointer and pointer to integer conversions.Warn for suspicious integer expressions in boolean context.Warn when there is a cast to a pointer from an integer of a different size.Warn about constant integer divisions with truncated results.Warn if a user-procedure has the same name as an intrinsic.Warn on intrinsics not part of the selected standard.Warn when an atomic memory model parameter is known to be outside the valid range.Warn about invalid uses of the "offsetof" macro.Warn about PCH files that are found but not used.Warn when a jump misses a variable initialization.-Wlarger-than= Warn if an object is larger than bytes.Warn about truncated source lines.Warn when a string or character literal is followed by a ud-suffix which does not begin with an underscore.Warn when logical not is used on the left hand side operand of a comparison.Warn when a logical operator is suspiciously always evaluating to true or false.Do not warn about using "long long" when -pedantic.During link time optimization warn about mismatched types of global declarations.Warn about suspicious declarations of "main".Warn about maybe uninitialized automatic variables.Warn about suspicious calls to memset where the third argument contains the number of elements not multiplied by the element size.Warn about suspicious calls to memset where the third argument is constant literal zero and the second is not.Warn when the indentation of the code does not reflect the block structure.Warn about declarations of entities that may be missing attributes that related entities have been declared with it.Warn about possibly missing braces around initializers.Warn about global functions without previous declarations.Warn about missing fields in struct initializers.Warn about user-specified include directories that do not exist.Warn about function parameters declared without a type specifier in K&R-style functions.Warn about global functions without prototypes.switch %qs is no longer supportedWarn about use of multi-character character constants.Warn on direct multiple inheritance.Warn about unsafe macros expanding to multiple statements used as a body of a clause such as if, else, while, switch, or for.Warn about narrowing conversions within { } that are ill-formed in C++11.Warn about "extern" declarations not at file scope.Warn when a noexcept expression evaluates to false even though the expression can't actually throw.Warn if C++17 noexcept function type will change the mangled name of a symbol.Warn when non-templatized friend functions are declared within a template.Warn about non-virtual destructors.Warn about NULL being passed to argument slots marked as requiring non-NULL.Warn if comparing pointer parameter with nonnull attribute with NULL.-Wnormalized=[none|id|nfc|nfkc] Warn about non-normalized Unicode strings.Warn if dereferencing a NULL pointer may lead to erroneous or undefined behavior.Warn about some C++ One Definition Rule violations during link time optimization.Warn if a C-style cast is used in a program.Warn for obsolescent usage in a declaration.Warn if an old-style parameter definition is used.Warn if a simd directive is overridden by the vectorizer cost model.Warn about overflow in arithmetic expressions.Warn if a string is longer than the maximum portable length specified by the standard.Warn about overloaded virtual function names.Warn about overriding initializers without side effects.Warn about overriding initializers with side effects.Warn when the packed attribute has no effect on struct layout.Warn about packed bit-fields whose offset changed in GCC 4.4.Warn when fields in a struct with the packed attribute are misaligned.Warn when padding is required to align structure members.Warn about possibly missing parentheses.Issue warnings needed for strict compliance to the standard.Warn for placement new expressions with undefined behavior.Warn when converting the type of pointers to member functions.Warn about function pointer arithmetic.Warn when a pointer is compared with a zero character constant.Warn when a pointer differs in signedness in an assignment.Warn when a pointer is cast to an integer of a different size.Warn about misuses of pragmas.Warn if a property for an Objective-C object has no assign semantics specified.Warn if inherited methods are unimplemented.Warn about real-literal-constants with 'q' exponent-letter.Warn when a left-hand-side array variable is reallocated.Warn when a left-hand-side variable is reallocated.Warn about multiple declarations of the same object.Warn about uses of register storage specifier.Warn when the compiler reorders code.Warn when an argument passed to a restrict-qualified parameter aliases with another argument.Warn about returning a pointer/reference to a local or temporary variable.Warn whenever a function's return type defaults to "int" (C), or about inconsistent return types (C++).Warn on suspicious constructs involving reverse scalar storage order.Warn if a selector has multiple methods.Warn about possible violations of sequence point rules.Warn when one variable shadows another. Same as -Wshadow=global.Warn if a local declaration hides an instance variable.Warn when one local variable shadows another local variable or parameter of compatible type.Warn when one variable shadows another (globally).Warn when one local variable shadows another local variable or parameter.Warn if shift count is negative.Warn if shift count >= width of type.Warn if left shifting a negative value.Warn if left shift of a signed value overflows.Warn about signed-unsigned comparisons.Warn for implicit type conversions between signed and unsigned integers.Warn when overload promotes from unsigned to signed.Warn about missing sized deallocation functions.Warn when sizeof is applied on a parameter declared as an array.Warn about suspicious divisions of two sizeof expressions that don't work correctly with pointers.Warn about suspicious length parameters to certain string functions if the argument uses sizeof.Warn when not issuing stack smashing protection for some reason.-Wstack-usage= Warn if stack usage might be larger than specified amount.Warn about code which might break strict aliasing rules.Warn about uncasted NULL used as sentinel.Warn about optimizations that assume that signed overflow is undefined.Warn about unprototyped function declarations.Warn if type signatures of candidate methods do not match exactly.Warn about buffer overflow in string manipulation functions like memcpy and strcpy.Under the control of Object Size type, warn about buffer overflow in string manipulation functions like memcpy and strcpy.Warn about truncation in string manipulation functions like strncat and strncpy.Warn if a class type has a base or a field whose type uses the anonymous namespace or depends on a type with no linkage.Warn about functions which might be candidates for __attribute__((cold)).Warn about functions which might be candidates for __attribute__((const)).Warn about functions which might be candidates for format attributes.Warn about functions which might be candidates for __attribute__((malloc)).Warn about functions which might be candidates for __attribute__((noreturn)).Warn about functions which might be candidates for __attribute__((pure)).Warn about C++ virtual methods where adding final keyword would improve code quality.Warn about C++ polymorphic types where adding final keyword would improve code quality.Suggest that the override keyword be used when the declaration of a virtual function overrides another.Warn about "suspicious" constructs.Warn about enumerated switches, with no default, missing a case.Warn about switches with boolean controlling expression.Warn about enumerated switches missing a "default:" statement.Warn about all enumerated switches missing a specific case.Warn about statements between switch's controlling expression and the first case.Warn when __sync_fetch_and_nand and __sync_nand_and_fetch built-in functions are used.Deprecated. This switch has no effect.Do not suppress warnings from system headers.Permit nonconforming uses of the tab character.Warn if the pointer in a pointer assignment might outlive its target.Warn if a comparison always evaluates to true or false.Warn on primary template declaration.Warn if a throw expression will always result in a call to terminate().Warn about features not present in traditional C.Warn of prototypes causing type conversions different from what would happen in the absence of prototype.Warn whenever a trampoline is generated.Warn if trigraphs are encountered that might affect the meaning of the program.Warn if a comparison is always true or always false due to the limited range of the data type.Warn about @selector()s without previously declared methods.Warn if an undefined macro is used in an #if directive.Warn about an invalid DO loop.Warn about underflow of numerical constant expressions.Warn about uninitialized automatic variables.Warn about unrecognized pragmas.Does nothing. Preserved for backward compatibility.Warn about unsuffixed float constants.Enable all -Wunused- warnings.Warn when a function parameter is only set, otherwise unused.Warn when a variable is only set, otherwise unused.Warn when a const variable is unused.Warn about unused dummy arguments.Warn when a function is unused.Warn when typedefs locally defined in a function are not used.Warn about macros defined in the main file that are not used.Warn when a function parameter is unused.Warn if a caller of a function, marked with attribute warn_unused_result, does not use its return value.Warn when an expression value is unused.Warn when a variable is unused.Warn about USE statements that have no ONLY qualifier.Warn about questionable usage of the macros used to retrieve variable arguments.Warn about using variadic macros.-Wvector-operation-performanceWarn when a vector operation is compiled outside the SIMD.Warn on direct virtual inheritance.Warn if a virtual base has a non-trivial move assignment operator.Warn if a variable length array is used.-Wvla-larger-than= Warn on unbounded uses of variable-length arrays, and on bounded uses of variable-length arrays whose bound can be larger than bytes.Warn when a register variable is declared volatile.In C++, nonzero means warn about deprecated conversion from string literals to 'char *'. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard.-Wzero-as-null-pointer-constantWarn when a literal '0' is used as null pointer.Warn about zero-trip DO loops.A synonym for -std=c89 (for C) or -std=c++98 (for C++).-aux-info Emit declaration information into .-d Enable dumps from specific passes of the compiler.-dumpbase Set the file basename to be used for dumps.-dumpdir Set the directory name to be used for dumps.Generate position-independent code if possible (large mode).Generate position-independent code for executables if possible (large mode).The version of the C++ ABI used for -Wabi warnings and link compatibility aliases.The version of the C++ ABI in use.Enforce class member access control semantics.-fada-spec-parent=unit Dump Ada specs as child units of given parent.-faggressive-function-eliminationEliminate multiple function invocations also for impure functions.-faggressive-loop-optimizationsAggressively optimize loops using language constraints.Enable alignment of COMMON blocks.Align labels which are only reached by jumping.Support C++17 allocation of over-aligned types.-faligned-new= Use C++17 over-aligned type allocation for alignments greater than N.All intrinsics procedures are available regardless of selected standard.-fallow-parameterless-variadic-functionsAllow variadic functions without named parameter.-fasan-shadow-offset= Use custom shadow memory offset.Allow optimization for floating-point arithmetic which may change the result of the operation due to rounding.Generate unwind tables that are exact at each instruction boundary.Generate auto-inc/dec instructions.Use sample profile information for call graph node weights. The default profile file is fbdata.afdo in 'pwd'.Use sample profile information for call graph node weights. The profile file is specified in the argument.Do not treat local variables and COMMON blocks as if they were named in SAVE statements.Specify that backslash in string introduces an escape character.Produce a backtrace when a runtime error is encountered.-fblas-matmul-limit= Size of the smallest matrix for which matmul will use BLAS.Generate code to check bounds before indexing arrays.Replace add, compare, branch with branch on count register.Use profiling information for branch probabilities.Perform branch target load optimization before prologue / epilogue threading.-fbranch-target-load-optimize2Perform branch target load optimization after prologue / epilogue threading.Restrict target load migration not to re-use registers in any basic block.Generate C prototypes from BIND(C) declarations.-fcall-saved- Mark as being preserved across functions.-fcall-used- Mark as being corrupted by function calls.Save registers around function calls.Where shorter, use canonicalized paths to systems headers.-fcf-protection=[full|branch|return|none] Instrument functions with checks to verify jump/call/return control-flow transfer instructions have valid targets.Produce a warning at runtime if a array temporary has been created for a procedure argument.This switch is deprecated; do not use.Check the return value of new in C++.Add Pointer Bounds Checker instrumentation. fchkp-* flags are used to control instrumentation. Currently available for C, C++ and ObjC.-fcheck=[...] Specify which runtime checks are to be performed.Perform internal consistency checkings.Generate pointer bounds checks for variables with incomplete type.Generate checks for all read accesses to memory.Generate checks for all write accesses to memory.-fchkp-first-field-has-own-boundsForces Pointer Bounds Checker to use narrowed bounds for address of the first field in the structure. By default pointer to the first field has the same bounds as pointer to the whole structure.-fchkp-flexible-struct-trailing-arraysForces Pointer Bounds Checker to treat all trailing arrays in structures as possibly flexible. By default only arrays fields with zero length or that are marked with attribute bnd_variable_size are treated as flexible.Generate bounds passing for calls.Instrument only functions marked with bnd_instrument attribute.Control how Pointer Bounds Checker handle pointers to object fields. When narrowing is on, field bounds are used. Otherwise full object bounds are used.-fchkp-narrow-to-innermost-arrayForces Pointer Bounds Checker to use bounds of the innermost arrays in case of nested static arrays access. By default outermost array is used.Allow Pointer Bounds Checker optimizations. By default allowed on optimization levels >0.Generate bounds stores for pointer writes.-fchkp-treat-zero-dynamic-size-as-infiniteWith this option zero size obtained dynamically for objects with incomplete type will be treated as infinite.-fchkp-use-fast-string-functionsAllow to use *_nobnd versions of string functions by Pointer Bounds Checker.-fchkp-use-nochk-string-functionsAllow to use *_nochk versions of string functions by Pointer Bounds Checker.Use statically initialized variable for vars bounds instead of generating them each time it is required.-fchkp-use-static-const-boundsUse statically initialized variable for constant bounds instead of generating them each time it is required.Transform instrumented builtin calls into calls to wrappers.-fchkp-zero-input-bounds-for-mainUse zero bounds for all incoming arguments in 'main' function. It helps when instrumented binaries are used with legacy libs.Deprecated in GCC 8. This switch has no effect.-fcoarray= Specify which coarray parallelization should be used.Looks for opportunities to reduce stack adjustments and stack references.Do not put uninitialized globals in the common section.Run only the second compilation of -fcompare-debug.-fcompare-debug[=] Compile with and without e.g. -gtoggle, and compare the final-insns dump.Perform comparison elimination after register allocation has finished.Enable support for C++ concepts.Allow the arguments of the '?' operator to have different types.Does nothing. Preserved for backward compatibility.Do not perform optimizations increasing noticeably stack usage.-fconst-string-class= Use class for constant strings.no class name specified with %qs-fconstexpr-depth= Specify maximum constexpr recursion depth.-fconstexpr-loop-limit= Specify maximum constexpr loop iteration count.-fconvert= The endianness used for unformatted files.Perform a register copy-propagation optimization pass.Use the Cray Pointer extension.Perform cross-jumping optimization.When running CSE, follow jumps to their targets.Complex multiplication and division follow Fortran rules.Omit range reduction step when performing complex division.Ignore 'D' in column one in fixed form.Treat lines with 'D' in column one as comments.Place data items into their own section.List all available debugging counters with their limits and counts.-fdbg-cnt=:[,:,...] Set the debug counter limit.Use the RTL dead code elimination pass.Emit debug annotations during preprocessing.-fdebug-prefix-map== Map one directory name to another in debug information.Output .debug_types section when using DWARF v4 debuginfo.Enable all DEC language extensions.Enable kind-specific variants of integer intrinsic functions.Enable legacy math intrinsics for compatibility.Enable DEC-style STATIC and AUTOMATIC attributes.Enable support for DEC STRUCTURE/RECORD.Factor complex constructors and destructors to favor space over speed.-fdeduce-init-list enable deduction of std::initializer_list for a template type parameter from a brace-enclosed initializer-list.Set the default double precision kind to an 8 byte wide type.Set the default integer kind to an 8 byte wide type.Set the default real kind to an 10 byte wide type.Set the default real kind to an 16 byte wide type.Set the default real kind to an 8 byte wide type.Defer popping functions args from stack until later.Attempt to fill delay slots of branch instructions.Delete dead instructions that may throw exceptions.Delete useless null pointer checks.Try to convert virtual calls to direct ones.Stream extra data to support more aggressive devirtualization in LTO local transformation mode.Perform speculative devirtualization.-fdiagnostics-color=[never|always|auto] Colorize diagnostics.Print fix-it hints to stderr in unified diff format.-fdiagnostics-parseable-fixitsPrint fix-it hints in machine-readable form.Show the source line with a caret indicating the column.-fdiagnostics-show-location=[once|every-line] How often to emit source location at the beginning of line-wrapped diagnostics.Amend appropriate diagnostic messages with the command line option that controls them.-fdiagnostics-show-template-treePrint hierarchical comparisons when template types are mismatched.-fdisable-[tree|rtl|ipa]-=range1+range2 disables an optimization pass.Allow dollar signs in entity names.Permit '$' as an identifier character.Use the RTL dead store elimination pass.-fdump- Dump various compiler internals to a file.Write all declarations as Ada code transitively.Write all declarations as Ada code for the given file only.-fdump-final-insns=filename Dump to filename the insns at the end of translation.Display the code tree after front end optimization.Display the code tree after parsing.-fdump-go-spec=filename Write all declarations to file as Go code.Dump detailed information on GCC's internal representation of source code locations.Suppress output of addresses in debugging dumps.Display the code tree after parsing; deprecated option.Suppress output of instruction numbers, line number notes and addresses in debugging dumps.Suppress output of previous and next insn numbers in debugging dumps.Enable CFI tables via GAS assembler directives.-fno-elide-type Do not elide common elements in template comparisons.-feliminate-unused-debug-symbolsPerform unused symbol elimination in debug info.-feliminate-unused-debug-typesPerform unused type elimination in debug info.Do not suppress C++ class debug information.-femit-struct-debug-baseonly Aggressive reduced debug info for structs.-femit-struct-debug-detailed= Detailed reduced debug info for structs.-femit-struct-debug-reduced Conservative reduced debug info for structs.-fenable-[tree|rtl|ipa]-=range1+range2 enables an optimization pass.Generate code to check exception specifications.-fexcess-precision=[fast|standard] Specify handling of excess floating-point precision.-fexec-charset= Convert all strings and character constants to character set .Perform a number of minor, expensive optimizations.Interpret imaginary, fixed-point, or other gnu number suffix as the corresponding number literal rather than a user-defined number literal.Permit universal character names (\u and \U) in identifiers.Support dynamic initialization of thread-local variables in a different translation unit.Specify that an external BLAS library should be used for matmul calls on large-size arrays.Output lto objects containing both the intermediate language and binary output.-ffile-prefix-map== Map one directory name to another in compilation result.Assume no NaNs or infinities are generated.-ffixed- Mark as being unavailable to the compiler.Assume that the source file is fixed form.-ffixed-line-length- Use n as character line width in fixed mode.Allow arbitrary character line width in fixed mode.Don't allocate floats and doubles in extended-precision registers.Scope of for-init-statement variables is local to the loop.Perform a forward propagation pass on RTL.-ffp-contract=[off|on|fast] Perform floating-point expression contraction.Allow built-in functions ceil, floor, round, trunc to raise "inexact" exceptions.-ffpe-summary=[...] Print summary of floating point exceptions.-ffpe-trap=[...] Stop on following floating point exceptions.Assume that the source file is free form.-ffree-line-length- Use n as character line width in free mode.Allow arbitrary character line width in free mode.Do not assume that standard C libraries and "main" exist.Inject friend functions into enclosing namespace.Try to interchange loops if profitable.Enable front end optimization.Allow function addresses to be held in registers.Place each function into its own section.Perform global common subexpression elimination.Perform global common subexpression elimination after register allocation has finished.Perform redundant load after store elimination in global common subexpression elimination.Perform enhanced load motion during global common subexpression elimination.Perform store motion after global common subexpression elimination.-fgnat-encodings=[all|gdb|minimal] Select the balance between GNAT encodings and standard DWARF emitted in the debug informationRecognize GNU-defined keywords.Generate code for GNU runtime environment.Enable support for GNU transactional memory.Use STB_GNU_UNIQUE if supported by the assembler.Use traditional GNU semantics for inline functions.-fgo-c-header= Write Go struct definitions to file as C code.Add explicit checks for division overflow in INT_MIN / -1.Add explicit checks for division by zero.Apply special rules for compiling runtime package.Emit debugging information related to the escape analysis pass when run with -fgo-optimize-allocs.-fgo-debug-escape-hash= Hash value to debug escape analysis.-fgo-dump- Dump Go frontend internal information.-fgo-optimize- Turn on optimization passes in the frontend.-fgo-pkgpath= Set Go package path.-fgo-prefix= Set package-specific prefix for exported Go names.-fgo-relative-import-path= Treat a relative import as relative to path.Enable in and out of Graphite representation.Enable Graphite Identity transformation.Enable guessing of branch probabilities.-fhandle-exceptions has been renamed -fexceptions (and is now on by default)Enable hoisting adjacent loads to encourage generating conditional move instructions.Assume normal C execution environment.Perform conversion of conditional jumps to branchless equivalents.Perform conversion of conditional jumps to conditional execution.Export functions even if they can be inlined.Emit implicit instantiations of inline templates.Specify that no implicit typing is allowed, unless overridden by explicit IMPLICIT statements.Emit implicit instantiations of templates.Do not generate .size directives.-finit-character= Initialize local character variables to ASCII value n.Initialize components of derived type variables according to other init flags.-finit-integer= Initialize local integer variables to n.Initialize local variables to zero (from g77).-finit-logical= Initialize local logical variables.-finit-real= Initialize local real variables.Enable inlining of function declared "inline", disabling disables all inlining.Inline __atomic operations when a lock free instruction sequence is available.Integrate functions not declared "inline" into their callers when profitable.-finline-functions-called-onceIntegrate functions only required by their single caller.-finline-limit= Limit the size of inlined functions to .-finline-matmul-limit= Specify the size of the largest matrix for which matmul will be inlined.Integrate functions into their callers when code size is known not to grow.-finput-charset= Specify the default character set for source files.Instrument function entry and exit with profiling calls.-finstrument-functions-exclude-file-list=-finstrument-functions-exclude-file-list=filename,... Do not instrument functions listed in files.-finstrument-functions-exclude-function-list=-finstrument-functions-exclude-function-list=name,... Do not instrument listed functions.Interpret any INTEGER(4) as an INTEGER(8).Specify where to find the compiled intrinsic modules.Perform interprocedural bitwise constant propagation.Perform interprocedural constant propagation.Perform cloning to make Interprocedural constant propagation stronger.Perform Identical Code Folding for functions and read-only variables.Perform Identical Code Folding for functions.Perform Identical Code Folding for variables.Perform interprocedural profile propagation.Perform interprocedural points-to analysis.Discover pure and const functions.Use caller save register across calls if possible.Discover readonly and non addressable static variables.Perform interprocedural reduction of aggregates.Perform IPA Value Range Propagation.-fira-algorithm=[CB|priority] Set the used IRA algorithm.Use IRA based register pressure calculation in RTL hoist optimizations.Use IRA based register pressure calculation in RTL loop optimizations.-fira-region=[one|all|mixed] Set regions for IRA.Share slots for saving different hard registers.Share stack slots for spilled pseudo-registers.-fira-verbose= Control IRA's level of diagnostic messages.-fisolate-erroneous-paths-attributeDetect paths that trigger erroneous or undefined behavior due to a null value being used in a way forbidden by a returns_nonnull or nonnull attribute. Isolate those paths from the main control flow and turn the statement with erroneous or undefined behavior into a trap.-fisolate-erroneous-paths-dereferenceDetect paths that trigger erroneous or undefined behavior due to dereferencing a null pointer. Isolate those paths from the main control flow and turn the statement with erroneous or undefined behavior into a trap.-fvisibility=[private|protected|public|package] Set the default symbol visibility.Optimize induction variables on trees.Use jump tables for sufficiently large switch statements.Don't emit dllexported inline functions unless needed.Generate code for functions even if they are fully inlined.Emit static const variables even if they are not used.Generate code for static functions even if they are never called.Allow implicit conversions between vectors with differing numbers of subparts and/or differing element types.Give external symbols a leading underscore.Tell DSE that the storage for a C++ object is dead when the constructor starts and when the destructor finishes.Set linker output type (used internally during LTO optimization)-flive-patching=[inline-only-static|inline-clone] Control IPA optimizations to provide a safe compilation for live-patching. At the same time, provides multiple-level control on the enabled IPA optimizations.Relief of register pressure through live range shrinkage.Allow access to instance variables as if they were local declarations within instance method implementations.Enable loop nest transforms. Same as -floop-nest-optimize.Enable loop interchange on trees.Enable the loop nest optimizer.Perform unroll-and-jam on loops.Do CFG-sensitive rematerialization in LRA.Enable link-time optimization.-flto-compression-level= Use zlib compression level for IL.Merge C++ types using One Definition Rule.Specify the algorithm to partition symbols and vars at linktime.Report various link-time optimization statistics.Report various link-time optimization statistics for WPA only.Link-time optimization with number of parallel jobs or jobserver.Run the link-time optimizer in local transformation (LTRANS) mode.Specify a file to which a list of files output by LTRANS is written.-fmacro-prefix-map== Map one directory name to another in __FILE__, __BASE_FILE__, and __builtin_FILE().Set errno after built-in math functions.-fmax-array-constructor= Maximum number of objects in an array constructor.-fmax-errors= Maximum number of errors to report.-fmax-identifier-length= Maximum identifier length.-fmax-stack-var-size= Size in bytes of the largest array that will be put on the stack.-fmax-subrecord-length= Maximum length for subrecords.Report on permanent memory allocation.Report on permanent memory allocation in WPA only.Attempt to merge identical constants and constant variables.Attempt to merge identical constants across compilation units.Attempt to merge identical debug strings across compilation units.-fmessage-length= Limit diagnostics to characters per line. 0 suppresses line-wrapping.Set default accessibility of module entities to PRIVATE.Perform SMS based modulo scheduling before the first scheduling pass.Perform SMS based modulo scheduling with register moves allowed.Move loop invariant computations out of loops.Don't warn about uses of Microsoft extensions.Implement C++17 inheriting constructor semantics.Implement resolution of DR 150 for matching of template template arguments.Generate code for NeXT (Apple Mac OS X) runtime environment.Assume that receivers of Objective-C messages may be nil.Support synchronous non-call exceptions.Treat a throw() exception specification as noexcept to improve code size.Specify which ABI to use for Objective-C family code and meta-data generation.Generate special Objective-C methods to initialize/destroy non-POD C++ ivars, if needed.Allow fast jumps to the message dispatcher.Enable Objective-C exception and synchronization syntax.Enable garbage collection (GC) in Objective-C/Objective-C++ programs.Enable inline checks for nil receivers with the NeXT runtime and ABI version 2.Enable Objective-C setjmp exception handling runtime.Conform to the Objective-C 1.0 language as implemented in GCC 4.0.-foffload-abi=[lp64|ilp32] Set the ABI to use in an offload compiler.-foffload== Specify offloading targets and options for them.options or targets missing after %qsWhen possible do not generate stack frames.Specify default OpenACC compute dimensions.Enable OpenMP (implies -frecursive in Fortran).Enable OpenMP's SIMD directives.Recognize C++ keywords like "compl" and "xor".Enable all optimization info dumps on stderr.-fopt-info[-=filename] Dump compiler optimization details.Optimize sibling and tail recursive calls.Enable string length optimizations on trees.Try to lay out derived types as compactly as possible.Pack structure members together without holes.-fpack-struct= Set initial maximum structure member alignment.Insert NOP instructions at each function entry.Return small aggregates in memory, not registers.Look for and use PCH files even when preprocessing.Enable machine specific peephole optimizations.Enable an RTL peephole pass before sched2.Downgrade conformance errors to warnings.-fpermitted-flt-eval-methods=[c11|ts-18661] Specify which values of FLT_EVAL_METHOD are permitted.Generate position-independent code if possible (small mode).Generate position-independent code for executables if possible (small mode).Enable Plan 9 language extensions.Use PLT for PIC calls (-fno-plt: load the address from GOT at call site).-fplugin-arg--[=] Specify argument = for plugin .Report on memory allocation before interprocedural optimization.Run predictive commoning optimization.Generate prefetch instructions, if available, for arrays in loops.Treat the input file as already preprocessed.-fno-pretty-templates Do not pretty-print template specializations as the template signature followed by the arguments.Treat known sprintf return values as constants.Enable basic program profiling code.Generate absolute source path names for gcov.Insert arc-based program profiling code.Enable correction of flow inconsistent profile data input.Set the top-level directory for storing the profile data. The default is 'pwd'.Enable common options for generating profile info for profile feedback directed optimizations.Enable common options for generating profile info for profile feedback directed optimizations, and set -fprofile-dir=.Enable function reordering that improves code placement.Report on consistency of profile.-fprofile-update=[single|atomic|prefer-atomic] Set the profile update method.Enable common options for performing profile feedback directed optimizations.Enable common options for performing profile feedback directed optimizations, and set -fprofile-dir=.Insert code to profile values of expressions.Protect parentheses in expressions.-frandom-seed= Make compile reproducible using .Enable range checking during compilation.Interpret any REAL(4) as a REAL(10).Interpret any REAL(4) as a REAL(16).Interpret any REAL(4) as a REAL(8).Interpret any REAL(8) as a REAL(10).Interpret any REAL(8) as a REAL(16).Interpret any REAL(8) as a REAL(4).Reallocate the LHS in assignments.Same as -fassociative-math for expressions which include division.Record gcc command line switches in the object file.Use a 4-byte record marker for unformatted files.Use an 8-byte record marker for unformatted files.Allocate local variables on the stack to allow indirect recursion.Turn on Redundant Extensions Elimination pass.Return small aggregates in registers.Perform a register renaming optimization pass.Reorder basic blocks to improve code placement.-freorder-blocks-algorithm=[simple|stc] Set the used basic block reordering algorithm.-freorder-blocks-and-partitionReorder basic blocks and partition into hot and cold sections.Reorder functions to improve code placement.Copy array sections into a contiguous block on procedure entry.Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime.Enable automatic template instantiation.Collect and dump debug information into temporary file if ICE in C/C++ compiler occurred.Functions which return values must end with return statements.Add a common subexpression elimination pass after loop optimizations.-freschedule-modulo-scheduled-loopsEnable/Disable the traditional scheduling in loops that already passed modulo scheduling.Disable optimizations that assume default FP rounding behavior.Generate run time type descriptor information.-fsanitize-address-use-after-scopeSelect type of coverage sanitization.This switch is deprecated; use -fsanitize-recover= instead.After diagnosing undefined behavior attempt to continue execution.-fsanitize-sections= Sanitize global variables in user-defined sections.-fsanitize-undefined-trap-on-errorUse trap instead of a library function for undefined behavior sanitization.-fsched-critical-path-heuristicEnable the critical path heuristic in the scheduler.Enable the dependent count heuristic in the scheduler.Enable the group heuristic in the scheduler.Enable scheduling across basic blocks.Enable the last instruction heuristic in the scheduler.Enable register pressure sensitive insn scheduling.Enable the rank heuristic in the scheduler.Allow speculative motion of non-loads.Enable the speculative instruction heuristic in the scheduler.Allow speculative motion of some loads.Allow speculative motion of more loads.Allow premature scheduling of queued insns.Set dependence distance checking in premature scheduling of queued insns.-fsched-stalled-insns-dep= Set dependence distance checking in premature scheduling of queued insns.-fsched-stalled-insns= Set number of queued insns that can be prematurely scheduled.-fsched-verbose= Set the verbosity level of the scheduler.If scheduling post reload, do superblock scheduling.Perform a target dependent instruction fusion optimization pass.Reschedule instructions before register allocation.Reschedule instructions after register allocation.Append a second underscore if the name already contains an underscore.Access data in the same section from shared anchor points.Perform software pipelining of inner loops during selective scheduling.-fsel-sched-pipelining-outer-loopsPerform software pipelining of outer loops during selective scheduling.-fsel-sched-reschedule-pipelinedReschedule pipelined regions without pipelining.Schedule instructions using selective scheduling algorithm.Run selective scheduling after reload.Run self-tests, using the given path to locate test files.Allow interposing function (or variables) by ones with different semantics (or initializer) respectively by dynamic linker.Use the narrowest integer type possible for enumeration types.Force the underlying type for "wchar_t" to be "unsigned short".Show column numbers in diagnostics, when available. Default on.Emit function prologues only before parts of the function that need it, rather than at the top of the function.Shrink-wrap parts of the prologue and epilogue separately.Apply negative sign to zero values.Disable optimizations observable by IEEE signaling NaNs.When "signed" or "unsigned" is not given make the bitfield signed.Make "char" signed by default.Disable floating point optimizations that ignore the IEEE signedness of zero.-fsimd-cost-model=[unlimited|dynamic|cheap] Specifies the vectorization cost model for code marked with a simd directive.Convert floating point constants to single precision constants.Enable C++14 sized deallocation support.Split lifetimes of induction variables when loops are unrolled.Split paths leading to loop backedges.Generate discontiguous stack frames.Split wide types into independent registers.Enable backward propagation of use properties at the SSA level.Optimize conditional patterns using SSA PHI nodes.-fsso-struct=[big-endian|little-endian|native] Set the default scalar storage order.Put all local arrays on stack.Insert stack checking code into the program. Same as -fstack-check=specific.-fstack-check=[no|generic|specific] Insert stack checking code into the program.Insert code to probe each page of stack space as it is allocated to protect from stack-clash style attacks.-fstack-limit-register= Trap if the stack goes past .-fstack-limit-symbol= Trap if the stack goes past symbol .Use propolice as a stack protection method.Use a stack protection method for every function.Use stack protection method only for functions with the stack_protect attribute.Use a smart stack protection method for certain functions.-fstack-reuse=[all|named_vars|none] Set stack reuse level for local variables.Output stack usage information on a per-function basis.Display statistics accumulated during compilation.Optimize amount of stdarg registers saved to stack at start of function.Assume strict aliasing rules apply.Assume that values of enumeration type are always within the minimum range of that type.Treat signed overflow as undefined. Negated as -fwrapv -fwrapv-pointer.Force bitfield accesses to match their type width.Follow the C++17 evaluation order requirements for assignment expressions, shift, member function calls, etc.Implement __atomic operations via libcalls to legacy __sync functions.Check for syntax errors, then stop.-ftabstop= Distance between tab stops for column reporting.Disallow tail call optimization when a calling routine may have omitted character lengths.Set the maximum number of template instantiation notes for a single warning or error.-ftemplate-depth= Specify maximum template instantiation depth.Create data files needed by "gcov".Force creation of temporary to test infrequently-executed forall code.Perform jump threading optimizations.-fno-threadsafe-statics Do not generate thread-safe code for initializing local statics.Report the time taken by each compiler pass.Record times taken by sub-phases separately.-ftls-model=[global-dynamic|local-dynamic|initial-exec|local-exec] Set the default thread-local storage code generation model.Reorder top level functions, variables, and asms.Perform superblock formation via tail duplication.-ftrack-macro-expansion=<0|1|2> Track locations of tokens coming from macro expansion and display them in error messages.For targets that normally need trampolines for nested functions, always generate them instead of using descriptors.Assume floating-point operations can trap.Trap for signed overflow in addition, subtraction and multiplication.Enable SSA-BIT-CCP optimization on trees.Enable conditional dead code elimination for builtin calls.Enable SSA-CCP optimization on trees.Enable loop header copying on trees.Enable SSA coalescing of user variables.Enable copy propagation on trees.Transform condition stores into unconditional ones.Enable SSA dead code elimination optimization on trees.Enable dominator optimizations.Enable dead store elimination.Enable forward propagation on trees.Enable Full Redundancy Elimination (FRE) on trees.-ftree-loop-distribute-patternsEnable loop distribution for patterns transformed into a library call.Enable loop distribution on trees.Convert conditional jumps in innermost loops to branchless equivalents.Enable loop invariant motion on trees.Create canonical induction variables in loops.Enable loop optimizations on tree level.Enable loop vectorization on trees.Perform live range splitting during the SSA->normal pass.-ftree-parallelize-loops= Enable automatic parallelization of loops.In SSA-PRE optimization on trees, enable partial-partial redundancy elimination.Enable hoisting loads from conditional pointers.Enable SSA-PRE optimization on trees.Perform function-local points-to analysis on trees.Enable reassociation on tree level.Enable copy propagation of scalar-evolution information.Enable SSA code sinking on trees.Enable basic block vectorization (SLP) on trees.Perform straight-line strength reduction.Perform scalar replacement of aggregates.Perform conversions of switch initializations.Replace temporary expressions in the SSA->normal pass.Enable vectorization on trees.Perform Value Range Propagation on trees.Assume common declarations may be overridden with ones with a larger trailing array.Append underscores to externally visible names.Compile whole compilation unit at a time.Perform loop unrolling for all loops.Perform loop unrolling when iteration count is known.Allow math optimizations that may violate IEEE or ISO standards.When "signed" or "unsigned" is not given make the bitfield unsigned.Make "char" unsigned by default.Just generate unwind tables for exception handling.Use __cxa_atexit to register destructors.Use __cxa_get_exception_ptr in exception handling.Use the bfd linker instead of the default linker.Use the gold linker instead of the default linker.Use the lld LLVM linker instead of the default linker.Perform variable tracking by annotating assignments.-fvar-tracking-assignments-toggleToggle -fvar-tracking-assignments.Perform variable tracking and also tag variables that are uninitialized.-fvariable-expansion-in-unrollerApply variable expansion when loops are unrolled.Enables the dynamic vectorizer cost model. Preserved for backward compatibility.Specifies the cost model for vectorization. -fvect-cost-model=[unlimited|dynamic|cheap] Specifies the cost model for vectorization.Add extra commentary to assembler output.Marks all inlined functions and methods as having hidden visibility.Changes visibility to match Microsoft Visual Studio by default.-fvisibility=[default|internal|hidden|protected] Set the default symbol visibility.Use expression value profiles in optimizations.Validate vtable pointers before using them.Output vtable verification counters.Output vtable verification pointer sets information.Emit common-like symbols as weak symbols.Construct webs and split unrelated uses of single variable.Perform whole program optimizations.-fwide-exec-charset= Convert all wide strings and character constants to character set .Generate a #line directive pointing at the current working directory.Run the link-time optimizer in whole program analysis (WPA) mode.Whole program analysis (WPA) mode with number of parallel jobs specified.Assume signed arithmetic overflow wraps around.Assume pointer overflow wraps around.Put zero initialized data in the bss section.Generate lazy class lookup (via objc_getClass()) for use in Zero-Link mode.Generate debug information in default format.Assume assembler support for (DWARF2+) .loc directivesAssume assembler support for view in (DWARF2+) .loc directivesswitch %qs no longer supportedRecord DW_AT_decl_column and DW_AT_call_column in DWARF.Generate debug information in default version of DWARF format.Generate debug information in DWARF v2 (or later) format.Dump declarations to a .decl file.Generate debug information in default extended format.Generate DWARF pubnames and pubtypes sections with GNU extensions.Generate extended entry point information for inlined functions-ginternal-reset-location-viewsCompute locview reset points based on insn length estimates-gnat Specify options to GNAT.Set name of output ALI file (internal switch).Don't generate DWARF pubnames and pubtypes sections.Generate DWARF pubnames and pubtypes sections.Record gcc command line switches in DWARF DW_AT_producer.Generate debug information in separate .dwo files.Generate debug information in STABS format.Generate debug information in extended STABS format.Emit progressive recommended breakpoint locations.Don't emit DWARF additions beyond selected version.Toggle debug information generation.Augment variable location lists with progressive views.-gvariable-location-views=incompat5Generate debug information in VMS format.Generate debug information in XCOFF format.Generate debug information in extended XCOFF format.Generate compressed debug sections.-gz= Generate compressed debug sections in format .-idirafter Add to the end of the system include path.-imacros Accept definition of macros in .-imultiarch Set to be the multiarch include subdirectory.-imultilib Set to be the multilib include subdirectory.-include Include the contents of before other files.-iplugindir= Set to be the default plugin directory.-iprefix Specify as a prefix for next two options.-iquote Add to the end of the quote include path.-isysroot Set to be the system root directory.-isystem Add to the start of the system include path.-iwithprefix Add to the end of the system include path.-iwithprefixbefore Add to the end of the main include path.Support 3DNow! built-in functions.Support Athlon 3Dnow! built-in functions.Expand 32bit/64bit integer divide into 8bit unsigned integer divide with run-time check.Generate code that conforms to the given ABI.Support code generation of Advanced Bit Manipulation (ABM) instructions.Reserve space for outgoing arguments in the function prologue.Support flag-preserving add-carry instructions.Support AES built-in functions and code generation.Align some doubles on dword boundary.Function starts are aligned to this power of 2.Jump targets are aligned to this power of 2.Loop code aligned to this power of 2.Align destination of the string operations.Generate code for the Android platform.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2 and AVX built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and AVX2 built-in functions and code generation.Split 32-byte AVX unaligned load.-mavx256-split-unaligned-storeSplit 32-byte AVX unaligned store.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and AVX5124FMAPS built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and AVX5124VNNIW built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and AVX512BITALG built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512BW built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512CD built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512DQ built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512ER built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512IFMA built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512PF built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512VBMI built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and AVX512VBMI2 built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512VL built-in functions and code generation.Support AVX512VNNI built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and AVX512VPOPCNTDQ built-in functions and code generation.Support BMI built-in functions and code generation.Support BMI2 built-in functions and code generation.Branches are this expensive (arbitrary units).Use libgcc stubs to save and restore registers clobbered by 64-bit Microsoft to System V ABI calls.Turn on CET instrumentation for switch statements that use a jump table and an indirect jump.Generate cld instruction in the function prologue.Support CLFLUSHOPT instructions.Support CLZERO built-in functions and code generation.%<-mcpu=%> is deprecated; use %<-mtune=%> or %<-march=%> insteadSupport code generation of crc32 instruction.Support code generation of cmpxchg16b instruction.Do dispatch scheduling if processor is bdver1, bdver2, bdver3, bdver4 or znver1 and Haifa scheduling is selected.Support F16C built-in functions and code generation.Generate sin, cos, sqrt for FPU.Emit profiling counter call at function entry before prologue.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and FMA built-in functions and code generation.Support FMA4 built-in functions and code generation.Always use Dynamic Realigned Argument Pointer (DRAP) to realign stack.Make all function calls indirect.Return values of functions in FPU registers.Generate floating point mathematics using given instruction set.Support FSGSBASE built-in functions and code generation.Convert function return to call and return thunk.%<-mfused-madd%> is deprecated; use %<-ffp-contract=%> insteadSupport FXSAVE and FXRSTOR instructions.Generate code which uses only the general registers.Support GFNI built-in functions and code generation.Generate code to mitigate against straight line speculation.Support Hardware Lock Elision prefixes.Generate code that conforms to Intel MCU psABI.Use IEEE math for fp comparisons.Assume incoming stack aligned to this power of 2.Add CS prefix to call and jmp to indirect thunk with branch target in r8-r15 registers.Force indirect call and jump via register.Convert indirect call and jump to call and return thunks.Inline all known string operations.-minline-stringops-dynamicallyInline memset/memcpy string operations, but perform inline version only for small blocks.%<-mintel-syntax%> and %<-mno-intel-syntax%> are deprecated; use %<-masm=intel%> and %<-masm=att%> instead-mlarge-data-threshold= Data greater than given threshold will go into .ldata section in x86-64 medium model.Support LWP built-in functions and code generation.Support LZCNT built-in function and code generation.Specify memcpy expansion strategy when expected size is known.Specify memset expansion strategy when expected size is known.Attempt to avoid generating instruction sequences containing ret bytes.Support MMX built-in functions.Support code generation of movbe instruction.Support MOVDIR64B built-in functions and code generation.Support MOVDIRI built-in functions and code generation.Use native (MS) bitfield layout.Support MWAITX and MONITORX built-in functions and code generation.Do not support SSE4.1 and SSE4.2 built-in functions and code generation.Generate mcount/__fentry__ calls as nops. To activate they need to be patched in.Omit the frame pointer in leaf functions.Set 80387 floating-point precision to 32-bit.Set 80387 floating-point precision to 64-bit.Set 80387 floating-point precision to 80-bit.Support PCLMUL built-in functions and code generation.Support PCONFIG built-in functions and code generation.Support PKU built-in functions and code generation.Support code generation of popcnt instruction.Use 128-bit AVX instructions instead of 256-bit AVX instructions in the auto-vectorizer.Use given register vector width instructions instead of maximum register width in the auto-vectorizer.Attempt to keep stack aligned to this power of 2.Support PREFETCHWT1 built-in functions and code generation.Support PREFETCHW instruction.Use push instructions to save outgoing arguments.Support RDPID built-in functions and code generation.Support RDRND built-in functions and code generation.Generate reciprocals instead of divss and sqrtss.Control generation of reciprocal estimates.Generate __mcount_loc section with all mcount or __fentry__ calls.Use red-zone in the x86-64 code.Number of registers used to pass integer arguments.Support RTM built-in functions and code generation.Support code generation of sahf instruction in 64bit x86-64 code.Support SGX built-in functions and code generation.Support SHA1 and SHA256 built-in functions and code generation.Enable shadow stack built-in functions from Control-flow Enforcement Technology (CET).Skip setting up RAX register when passing variable arguments.Support MMX and SSE built-in functions and code generation.Support MMX, SSE and SSE2 built-in functions and code generation.Encode SSE instructions with VEX prefix.Support MMX, SSE, SSE2 and SSE3 built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2 built-in functions and code generation.Support MMX, SSE, SSE2, SSE3, SSSE3 and SSE4.1 built-in functions and code generation.Support MMX, SSE, SSE2, SSE3 and SSE4A built-in functions and code generation.Use SSE register passing conventions for SF and DF mode.Support MMX, SSE, SSE2, SSE3 and SSSE3 built-in functions and code generation.-mstack-protector-guard-offset=Use the given offset for addressing the stack-protector guard.Use the given base register for addressing the stack-protector guard.-mstack-protector-guard-symbol=Use the given symbol for addressing the stack-protector guard.Use given stack-protector guard.Chose strategy to generate stringop using.Disable Scalar to Vector optimization pass transforming 64-bit integer computations into a vector ones.Support TBM built-in functions and code generation.Use given thread-local storage dialect.Use direct references against %gs when accessing tls data.Fine grain control of tune features.Support VAES built-in functions and code generation.Return 8-byte vectors in memory.Support VPCLMULQDQ built-in functions and code generation.Generate vzeroupper instruction before a transfer of control flow out of the function.Support WBNOINVD built-in functions and code generation.Support XOP built-in functions and code generation.Support XSAVE and XRSTOR instructions.Support XSAVES and XRSTORS instructions.Don't create a dynamically linked position independent executable.Do not search standard system include directories (those specified with -isystem will still be used).Do not search standard system include directories for C++.Do not look for object files in standard path.-o Place output into .Like -pedantic but issue them as errors.Create a dynamically linked position independent executable.Generate C header of platform-specific features.Do not display functions compiled or elapsed time.Remap file names when including files.Statically link the GNU Fortran helper library (libgfortran).Create a static position independent executable.Conform to the ISO 1998 C++ standard revised by the 2003 technical corrigendum.Deprecated in favor of -std=c++11.Conform to the ISO 2011 C++ standard.Conform to the ISO 2014 C++ standard.Conform to the ISO 2017 C++ standard.Deprecated in favor of -std=c++14.Deprecated in favor of -std=c++17.Conform to the ISO 2020(?) C++ draft standard (experimental and incomplete support).Conform to the ISO 2011 C standard.Conform to the ISO 2017 C standard (expected to be published in 2018).Deprecated in favor of -std=c11.Conform to the ISO 1990 C standard.Conform to the ISO 1999 C standard.Deprecated in favor of -std=c99.Conform to the ISO Fortran 2003 standard.Conform to the ISO Fortran 2008 standard.Conform to the ISO Fortran 2008 standard including TS 29113.Conform to the ISO Fortran 2018 standard.Conform to the ISO Fortran 95 standard.Conform to nothing in particular.Conform to the ISO 1998 C++ standard revised by the 2003 technical corrigendum with GNU extensions.Deprecated in favor of -std=gnu++11.Conform to the ISO 2011 C++ standard with GNU extensions.Conform to the ISO 2014 C++ standard with GNU extensions.Conform to the ISO 2017 C++ standard with GNU extensions.Deprecated in favor of -std=gnu++14.Deprecated in favor of -std=gnu++17.Conform to the ISO 2020(?) C++ draft standard with GNU extensions (experimental and incomplete support).Conform to the ISO 2011 C standard with GNU extensions.Conform to the ISO 2017 C standard (expected to be published in 2018) with GNU extensions.Deprecated in favor of -std=gnu11.Conform to the ISO 1990 C standard with GNU extensions.Conform to the ISO 1999 C standard with GNU extensions.Deprecated in favor of -std=gnu99.Conform to the ISO 1990 C standard as amended in 1994.Deprecated in favor of -std=iso9899:1999.Accept extensions to support legacy code.Enable traditional preprocessing.-trigraphs Support ISO C trigraphs.Do not predefine system-specific and GCC-specific macros.Display the compiler's version.Known assembler dialects (for use with the -masm= option):Known ABIs (for use with the -mabi= option):unknown Control-Flow Protection Level %qsKnown code models (for use with the -mcmodel= option):argument %qs to %<-Wbidi-chars%> not recognizedargument %qs to %<-Wnormalized%> not recognizedunknown excess precision style %qsunknown floating point contraction style %qsUnrecognized option to endianness value: %qsUnrecognized option to floating-point init value: %qsKnown choices for mitigation against straight line speculation with -mharden-sls=:Known indirect branch choices (for use with the -mindirect-branch=/-mfunction-return= options):unrecognized ivar visibility value %qsKnown data alignment choices (for use with the -malign-data= option):Known vectorization library ABIs (for use with the -mveclibabi= option):unknown Live-Patching Level %qsunknown LTO partitioning model %qsunknown specification for the set of FLT_EVAL_METHOD values to permit %qsKnown address mode (for use with the -maddress-mode= option):Known preferred register vector length (to use with the -mprefer-vector-width= option)unknown profile update method %qsunknown basic block reordering algorithm %qsunrecognized scalar storage order value %qsKnown stack protector guard (for use with the -mstack-protector-guard= option):Valid arguments to -mstringop-strategy=:unrecognized visibility value %qsKnown TLS dialects (for use with the -mtls-dialect= option):unknown vectorizer cost model %qsunknown vtable verify initialization priority %qsargument %qs to %<-Waligned-new%> not recognized../../gcc/hash-table.h../../gcc/vec.cHash tablesHash mapsHash setsHeap vectorsBitmapsGGC memoryAllocation pool%s:%i (%s)%-48s %10li:%4.1f%%%10li%10li:%4.1f%%%11li%11li TimesPeakLeak%-48s %11s%15s%10s%17s%11s Peak itemsLeak itemsTotal%s%55li%25li%17li ../../gcc/mem-stats.halloc_entriescalculate_allocation_1alloc_entriesalloc_entriesrelease_overheadalloc_entriesY@../../gcc/hash-table.calloc_entriesalloc_entriesrelease_overheadhash_table_higher_prime_index%I$ <;G]tB{= 0$~`2fCOmA oE!a  0P AA ?  &*"@ `0PHX? "A!)?../../gcc/spellcheck.cget_lengthfind_closest_string../../gcc/common/config/i386/i386-common.c-malign-loops is obsolete, use -falign-loops-malign-loops=%d is not between 0 and %d-malign-jumps is obsolete, use -falign-jumps-malign-jumps=%d is not between 0 and %d-malign-functions is obsolete, use -falign-functions-malign-functions=%d is not between 0 and %d-mbranch-cost=%d is not between 0 and 5,,,,,t,,6 ,,Ӂ,,,,Ҋ,,ʃuKyO' p{Qa,e=,,,܀,,T2,,+,,̈,,,,,,`,,,,,,,,,,,,,,,,,ju,,,L,,,,,,,,,,,,,U,~~,,,~O~,/~},,,,,,}k}$}|6,,,kT ,,Ă,,,,,,,,,,,,,ԋ,,Ą,,R(Cix86_handle_option| ~pP~p@ ../../gcc/hooks.chook_int_rtx_insn_unreachable../../gcc/diagnostic.c [fix-it::{%i:%i-%i:%i}::%d:%dlocus%s %s%s%s%s%s%s:%sSee %s for instructions. compilation terminated. %s%s:%s ???0x%lx %s %s:%d %s%s%s COLUMNSin %s, at %s:%d\\\t\n\"\%o%o%otoplev::mainexecute_one_passcompile_filefatal error: internal compiler error: sorry, unimplemented: warning: anachronism: note: debug: pedwarn: permerror: must-not-happenwarningnoteInternal compiler error: Error reporting routines re-entered. %s:%d: confused by earlier errors, bailing out compilation terminated due to -fmax-errors=%u. In file included from %r%s%s%R, from %r%s%s%Rcompilation terminated due to -Wfatal-errors. Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. %s: all warnings being treated as errors%s: some warnings being treated as errorsk 99PPPPYYY internal_error_no_backtraceinternal_errorfatal_errorerror_atpermerrorpedwarnwarning_nwarning_atinformprint_escaped_stringprint_parseable_fixitsdiagnostic_action_after_outputdiagnostic_build_prefixdiagnostic_set_infodiagnostic_set_info_translated../../gcc/diagnostic.cTERMdumb../../gcc/diagnostic-color.cGCC_COLORSrange1range2fixit-insertfixit-deletediff-filenamediff-hunkdiff-deletediff-inserttype-diffcolorize_init../../gcc/diagnostic-show-locus.c|48xensure_terminatedoverwritesubspancolumn_rangeadd_hintintersects_line_pcontains_pointget_line_width_without_trailing_whitespacebegin_stateprint_leading_fixitsget_expanded_locationmaybe_add_location_rangeline_spancalculate_line_spanslayout../../gcc/edit-context.c@@ -%i,%i +%i,%i @@ --- %s +++ %s ensure_terminatedapply_fixitget_num_linesprint_run_of_changed_linesget_or_insert_fileget_file../../gcc/pretty-print.cqwl+#%ld%lld%lo%llo%p%lu%i%x%lx%llx\x%02x\%03o\U%08x\lx<==pp_output_formatted_textpp_formatpp_write_text_as_dot_label_to_stream/usr/share/locale`utf-8utf8‘’../../gcc/input.c%*cunoptimized_ranges: %i RESERVED LOCATIONSORDINARY MAP: %i file: %s starting at line: %i column and range bits: %i column bits: %i range bits: %i %s:%3i|loc:%5i|%.*s UNALLOCATED LOCATIONSMACRO %i: %s (%u tokens) map->start_location: %u macro_locations: %u: %u, %u token %u has x-location == %utoken %u has y-location == %uMAX_SOURCE_LOCATIONAD-HOC LOCATIONSmacro expansionrange endpoints are reversedunable to read source lineline is not wide enoughcaret_idx out of rangestart_idx out of rangeend_idx out of rangeseen line directivetrack_macro_expansion != 2unknown location source_location interval: %u <= loc < %u Number of expanded macros: %5ld Average number of tokens per macro expansion: %5ld Line Table allocations during the compilation process Number of ordinary maps used: %5ld%c Ordinary map used size: %5ld%c Number of ordinary maps allocated: %5ld%c Ordinary maps allocated size: %5ld%c Number of macro maps used: %5ld%c Macro maps used size: %5ld%c Macro maps locations size: %5ld%c Macro maps size: %5ld%c Duplicated maps locations size: %5ld%c Total allocated maps size: %5ld%c Total used maps size: %5ld%c Ad-hoc table size: %5ld%c Ad-hoc table entries used: %5ld expansion point is location %itoken %u has x-location == y-location == %ux-location == y-location == %u encodes token # %u range starts after LINE_MAP_MAX_LOCATION_WITH_COLSrange ends after LINE_MAP_MAX_LOCATION_WITH_COLSrange endpoints are in different filesrange endpoints are on different linesget_substring_ranges_for_locget_source_location_for_substringget_string_concatenationrecord_string_concatenationalloc_entriesalloc_entriesalloc_entriesrelease_overheaddump_location_infoexpand_location_1get_next_lineread_line_numtotal_lines_numdiagnostics_file_cache_forcibly_evict_file(GCC) 8.5.0 20210514 (Red Hat 8.5.0-28)failure to convert %s to %siconv_open../../libcpp/charset.cmissing open quoteempty character constant'$' in identifier or numbercpp_interpret_string_1 failedUTF-8/UTF-32LEUTF-8/UTF-32BEUTF-8/UTF-16LEUTF-8/UTF-16BEUTF-32LE/UTF-8UTF-32BE/UTF-8UTF-16LE/UTF-8UTF-16BE/UTF-8conversion from %s to %s not supported by iconvconverting UCN to source character setconverting UCN to execution character setthe meaning of '\x' is different in traditional C\x used with no following hex digitshex escape sequence out of rangeoctal escape sequence out of rangethe meaning of '\a' is different in traditional Cnon-ISO-standard escape sequence, '\%c'unknown escape sequence: '\%c'unknown escape sequence: '\%s'converting escape sequence to execution character setconverting to execution character setcharacter constant too long for its typemulti-character character constantuniversal character names are only valid in C++ and C99C99's universal character names are incompatible with C90the meaning of '\%c' is different in traditional CIn _cpp_valid_ucn but not a UCNincomplete universal character name %.*s%.*s is not a valid universal characterCharacter %x might not be NFKCuniversal character %.*s is not valid in an identifieruniversal character %.*s is not valid at the start of an identifiercharacter 0x%lx is not in the basic source character set character 0x%lx is not unibyte in execution character setexecution character set != source character setXnXnXunXuP~m@HmI~mmm)-/1Oihi      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMOPQRSTUVWXYZ[\]^_`abcdefghijklmnostyiz}(~lHmMmmhh   89OPQRSVW[\]^uw0VXY`m     !&:?JKLMNO P!Q"RSTUVWXYZ[\]^_iotmx/0123456789:;<=>?@ABCDEFGHI !"$%&()*+,XYZ   ( ) 0 1 3 4 9 ; < L M O P Q R S W _ b c e o         ( ) 0 1 2 3 4 5 6 7 9 ; = B F H J L M X [ \ ] ^ e o s t       ( ) 0 1 3 5 9 ; < = > C F G H J L M U W [ ] ^ a e o       ( ) 3 4 9 = D E G H I L M T TU [V _ a e o        ( ) 9 = > C E H I L M V W _ a e o    012m37g8g9 :?FGkHkIkJNOY[mvvzzzi h 3456789=B CGHL MQ RV W[ \h ipqr st viw xiyz{|        %&-.68 9hY`u\]^3 89:_tuvwxyz{~     345:;<=?ABCjklmnopqr  6+h./h:;hMNhjwhxh -/79KS[]ciw{mIEGMOWXYZ[\]^p qr st uv wx yz {| } h hH  H  H  H(  h ) . `> @ S T _ o hq s h~ i h h h          h!i!h!!h!i!!h !i!!i!h!!!i!!h"!#!i$!%! &!'!i(!)!)*! +!i-!.!i1!2!i8!h9!:!h@!D!hI!O!h_!i!!!h!!_$h$$u''+{,h},,,,n-ho-~----------------------------------..h..h..h//`000 0)0*0+0,0-0.0/00050h6070h:0@0K0L0M0N0O0P0Q0R0S0T0U0V0W0X0Y0Z0[0\0]0^0_0`0a0b0d0e0f0g0h0i0o0q0r0t0u0w0x0z0{0}000000m000h0000000000000000000000000000000000000000000000000h01,101h11h11h22hG2O2h~22h22h3Mnstuvwxyz{|ohphèߨ*+,R     ! "$ &) -mohh l) 67 <= >? AB DE Nll=?Olllhh !"#$%/hDFhRShfghkolrsltulh l:h@lZhelllllhh  7 8 9 > E &'-/2 3 ]defghlmnopqz{|}~ABChTUhhhhhhhhhh  hhh9:h>?hDEhFIhPQhhhhh h"#h$&h'(h23h78h9:h;AhBFhGHhIJhKLhOPhRShTVhWXhYZh[\h]^h_`hbchdfhjkhrshwxh|}h~hhhhhh h./hOihkhhh:?hHOhQ push_macropop_macropoisonsystem_headerunterminated #%s#%s is a GCC extensionempty filename in #%s#include nested too deeplypragma dependency#endif without #if"%s" re-assertedassertion without predicatemissing '(' after predicatepredicate's answer is empty#else without #if#else after #elsethe conditional began hereundefining "%s"#elif without #if#elif after #elseline number out of range"%s" is not a valid filenamepoisoning existing macro "%s"#pragma once in main fileinvalid #%s directivecannot find source file %scurrent file is older than %s( ../../libcpp/directives.cdefineendififdefifndefpragmainclude_nextunassertsccsregistering pragmas in namespace "%s" with mismatched name expansionregistering pragma "%s" with name expansion and no namespaceregistering "%s" as both a pragma and a pragma namespace#pragma %s %s is already registered#pragma %s is already registered"defined" cannot be used as a macro name"__has_include__" cannot be used as a macro name"%s" cannot be used as a macro name as it is an operator in C++no macro name given in #%s directivemacro names must be identifiersembedding a directive within macro arguments is not portablestyle of line directive is a GCC extension#%s is a deprecated GCC extensionsuggest not using #elif in traditional Ctraditional C ignores #%s with the # indentedsuggest hiding #%s from traditional C with an indented #invalid preprocessing directive #%s; did you mean #%s?invalid preprocessing directive #%s#%s expects "FILENAME" or extra tokens at end of #%s directivepredicate must be an identifiermissing ')' to complete answer#include_next in primary source fileunexpected end of file after #line"%s" after #line is not a positive integer#pragma system_header ignored outside include fileinvalid #pragma GCC poison directiveinvalid flag "%s" in line directiveinvalid "#pragma GCC %s" directivemissing terminating > characterinvalid #pragma push_macro directive"%s" after # is not a positive integerfile "%s" linemarker ignored due to incorrect nestingregistering pragma with NULL handler_Pragma takes a parenthesized string literalinvalid #pragma pop_macro directivecpp_pop_definitionstdoutcpplib%s: %s../../libcpp/errors.ccpp_diagnostic_with_linecpp_diagnostic_atuse of C++11 long long integer constantuse of C99 long long integer constantbinary constants are a C++14 feature or GCC extensionbinary constants are a GCC extensionmissing binary operator before token "%s"digit separator after base indicatordigit separator adjacent to decimal pointtoo many decimal points in numberdigit separator adjacent to exponentdigit separator outside digit sequencefixed-point constants are a GCC extensioninvalid digit "%c" in binary constantinvalid digit "%c" in octal constantinvalid prefix "0b" for floating constantno digits in hexadecimal floating constantuse of C++17 hexadecimal floating constantuse of C99 hexadecimal floating constanthexadecimal floating constants require an exponentinvalid suffix "%.*s" on floating constanttraditional C rejects the "%.*s" suffixsuffix for double constant is a GCC extensioninvalid suffix "%.*s" with hexadecimal floating constantdecimal float constants are a GCC extensioninvalid suffix "%.*s" on integer constantimaginary constants are a GCC extensionuser-defined literal in preprocessor expressionfloating constant in preprocessor expressioninteger constant is too large for its typeinteger constant is so large that it is unsignedimaginary number in preprocessor expressionoperator "defined" requires an identifier("%s" is an alternative token for "%s" in C++)this use of "defined" may not be portable"%s" is not defined, evaluates to 0assertions are a GCC extensionassertions are a deprecated extensiontoken "%s" is not valid in preprocessor expressionsmissing expression between '(' and ')'operator '%s' has no right operandoperator '%s' has no left operandthe left operand of "%s" changes sign when promotedthe right operand of "%s" changes sign when promotedtraditional C rejects the unary plus operatorinteger overflow in preprocessor expressioncomma operator in operand of #ifoperator "__has_include__" requires a header stringmissing ')' after "__has_include__"#elifadjacent digit separatorsexponent has no digitsmissing ')' after "defined"../../libcpp/expr.c%s with no expressionimpossible operator '%u'division by zero in #ifmissing ')' in expression'?' without following ':'missing '(' in expression ':' without preceding '?'unbalanced stack in %sL2''''''''''''''''|'2>>P+P+<&i22>>auaɪ88DDDDDDDDDDDD><<&&||EOF==!=+=-=*=/=%=&=|=^=>>=<<=->->*.*AT_NAMENUMBERWCHARCHAR16CHAR32UTF8CHAROTHERWSTRINGSTRING16STRING32UTF8STRINGOBJC_STRINGHEADER_NAMEWCHAR_USERDEFCHAR16_USERDEFCHAR32_USERDEFUTF8CHAR_USERDEFWSTRING_USERDEFSTRING16_USERDEFSTRING32_USERDEFUTF8STRING_USERDEFCOMMENTMACRO_ARGPRAGMAPRAGMA_EOLPADDING%:%:<::><%%>__VA_ARGS__ can only appear in the expansion of a C++11 variadic macro__VA_ARGS__ can only appear in the expansion of a C99 variadic macroidentifier "%s" is a special operator name in C++C++ style comments are not allowed in ISO C90(this will be reported only once per input file)C++ style comments are incompatible with C90unpaired UTF-8 bidirectional control character detectedbackslash-newline at end of filetrigraph ??%c ignored, use -trigraphs to enablebackslash and newline separated by spaceraw string delimiter longer than 16 charactersinvalid new-line in raw string delimiterinvalid character '%c' in raw string delimiterinvalid suffix on literal; C++11 requires a space between literal and string macronull character(s) preserved in literalmissing terminating %c characterC++11 requires a space between string literal and macroUTF-8 vs UCN mismatch when closing a context by "%s""%s" is closing an unopened contextfound problematic Unicode character "%s"__VA_OPT__ is not available until C++2a__VA_OPT__ can only appear in the expansion of a C++2a variadic macroU+202A (LEFT-TO-RIGHT EMBEDDING)U+202B (RIGHT-TO-LEFT EMBEDDING)U+202D (LEFT-TO-RIGHT OVERRIDE)U+202E (RIGHT-TO-LEFT OVERRIDE)U+2066 (LEFT-TO-RIGHT ISOLATE)U+2067 (RIGHT-TO-LEFT ISOLATE)U+202C (POP DIRECTIONAL FORMATTING)U+2069 (POP DIRECTIONAL ISOLATE)`````:@ ^8888888888@Y!!!v!ddddd>D$$b<<<<<<<<<<ѿԾD]%%%z% J8HJJ?2@@@@@@@@@@@@@@@@@@@@@@@A@@@@@@@@@@@@@@@@@@@@@@@@@@a=$N../../libcpp/line-map.cyesNoneLC_ENTERLC_LEAVELC_RENAMELC_RENAME_VERBATIMLC_ENTER_MACROFile: %s:%d Included from: [%d] %s Macro: %s (%u tokens) N/A# of ordinary maps: %d # of macro maps: %d Include stack depth: %d Highest location: %u Ordinary line maps Macro line maps line-map.c: file "%s" entered but not left Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s {P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}linemap_expand_locationlinemap_resolve_locationlinemap_compare_locations"%s" may not appear in macro parameter listmacro parameters must be comma-separatedanonymous variadic macros were introduced in C++11anonymous variadic macros were introduced in C99ISO C++ does not permit named variadic macrosISO C does not permit named variadic macrosmissing ')' in macro parameter listISO C++11 requires whitespace after the macro nameISO C99 requires whitespace after the macro namemissing whitespace after the macro name'#' is not followed by a macro parameter'##' cannot appear at either end of a macro expansion__VA_OPT__ may not appear in a __VA_OPT____VA_OPT__ must be followed by an open parenthesis'##' cannot appear at either end of __VA_OPT__this is the location of the previous definitionduplicate macro parameter "%s"unterminated argument list invoking macro "%s"function-like macro "%s" must be used with arguments in traditional Cinvalid string literal, ignoring final '\'invoking macro %s argument %d: empty macro arguments are undefined in ISO C++98invoking macro %s argument %d: empty macro arguments are undefined in ISO C90ISO C++11 requires at least one argument for the "..." in a variadic macroISO C99 requires at least one argument for the "..." in a variadic macromacro "%s" requires %u arguments, but only %u givenmacro "%s" passed %u arguments, but takes just %upasting "%s" and "%s" does not give a valid preprocessing tokeninvalid hash type %d in cpp_macro_definitionmacro "%s" might prevent reproducible buildscould not determine file timestampcould not determine date and time__COUNTER__ expanded inside directive with -fdirectives-onlymacro argument "%s" would be stringified in traditional Cparameter name missing!"#%&'()*+,-./:;<=>?[\]^{|}~unterminated __VA_OPT____STDC_"%s" redefined__STDC_FORMAT_MACROS__STDC_LIMIT_MACROS__STDC_CONSTANT_MACROS../../libcpp/macro.cinvalid built-in macro "%s""??? ??? ?? ??:??:?? ????""%s %2d %4d""%02d:%02d:%02d""??? ?? ????""??:??:??"macro "%s" is not usedJanFebMarAprMayJunJulAugSepOctNovDec<\7ټ{{ȼټ־_cpp_backup_tokensmacro_real_token_counttokens_buff_add_tokenpaste_all_tokensreached_end_of_context_cpp_pop_context_cpp_builtin_macro_text \ String pool entries %lu identifiers %lu (%.2f%%) slots %lu deleted %lu table size %lu%c coll/search %.4f ins/search %.4f ../../libcpp/symtab.clongest entry %lu bytes %lu%c (%lu%c overhead) avg. entry %.2f bytes (+/- %.2f) approx_sqrt-C6?syntax error in macro parameter listdetected recursion whilst expanding macro "%s"mmap/proc/self/exe/proc/curproc/file/proc/%ld/object/a.outfailed to read executable informationlibbacktrace could not find executable to opencloseno debug info in ELF executableno symbol table in ELF executableexecutable file is unrecognized ELF versionexecutable file is unexpected ELF classexecutable file has unknown endiannessELF symbol table strtab link out of rangesymbol string index out of range93-'!0w,aQ mjp5c飕d2yҗ+L |~-d jHqA}mQDžӃVlkdzbeO\lcc=  n;^iLA`rqgjm Zjz  ' }Dңhi]Wbgeq6lknv+ӉZzJgo߹ホCՎ`~ѡ8ROggW?K6H+ L J6`zA`Ugn1yiFafo%6hRw G "/&U;( Z+j\1е,[d&c윣ju m ?6grWJz+{8 Ғ |! ӆBhn[&wowGZpj;f\ eibkaElx TN³9a&g`MGiIwn>JjѮZf @;7SŞϲG0򽽊º0S$6к)WTg#.zfJah]+o*7 Z-                                         P p00 ` @P X x8@ h( H` T t48 d$DX \ |<H l,( Lh R r24 b"BT Z z:D j*$ Jd V v6< f&F\ ^  ~>L n.,Nl Q q12 a!AR Y y9B i)" Ib U u5: e%EZ ]  }=J m-* Mj S s36 c#CV [ {;F k+& Kf W w7> g'G^ _ ?N o/.Onexecutable file is not ELFELF section name out of range.note.gnu.build-idGNU.gnu_debuglink.opd/usr/lib/debug/.build-id/.debug//usr/lib/debug/fstat.debug_info.debug_line.debug_abbrev.debug_ranges.debug_str.zdebug_info.zdebug_line.zdebug_abbrev.zdebug_ranges.zdebug_strmunmap%s in %s at %dDWARF underflowLEB128 overflows uint64_tunrecognized address sizeDW_FORM_strp out of rangeunrecognized DWARF forminvalid abbreviation coderanges offset out of rangeunit line offset out of rangeunrecognized DWARF versionabbrev offset out of rangesigned LEB128 overflows uint64_tabstract origin or specification out of rangeinvalid abstract origin or specificationinvalid file number in DW_AT_call_file attributefunction ranges offset out of rangeunsupported line number versioninvalid directory index in line number program headerinvalid directory index in line number programinvalid file number in line number program&&'''8$8$i''8$8$'alnumalphablankcntrlgraphlowerprintpunctxdigitMemory exhaustedSuccessNo matchInvalid regular expressionInvalid collation characterInvalid character class nameTrailing backslashInvalid back referenceUnmatched [ or [^Unmatched ( or \(Unmatched \{Invalid content of \{\}Invalid range endRegular expression too bigUnmatched ) or \)bTaq2a``;;```b`bb\bcJLBM@@CBs4DEf+h D D?iDAL.iedddMLgfcahz?N?N?N?N?N`N?NuzzzzzNz?N?N?N?N?N?N?Ny?N?N?N?NzzzzyMMMMMy{MyyyyyyMMMMMMM{MMMMyyyy%yOMOMOMOMOMzOMy%y%y%y%y[yOMOMOMOMOMOMOMxOMOMOMOM%y%y%y%yVNMMMMMMMNVNVNVNVNiNMMMMMMMNMMMMVNVNVNVNNo previous regular expressionInvalid preceding regular expressionPremature end of regular expressionb}b}b}b}}}}}i}i}b}i}i}i}i}i}i}i}i}i}i}i}i}}t}t}t}t}t}t}t}t}b}i}i}i}i}i}}i}t}o}b}}b}t}t}o}}}i}i}i}b}b}b}b}b}i}b}b}i}b}}}i}i}i}}}}i}i}i}b}t}b}t}t}}}}|#}#}}}}}}}}}}}}}}}}}}#}}}}}}}}}}}||}}#}}}}}}}}}}#}}}}}}}}}}}}}}}#}#}}}}}}#}}}}}}}}}J݅݅_zI^!|ϋ$5FWhy݌++FFBBffJhrXhwhhҜҜؠ5Ϣȟ`6Oppppppppppееееееее#ݹе_MеееееKpϸе%wееееpееееее׵׵׵׵׵׵׵׵׵׵е׵׵׵׵еее׵׵5׵׵׵׵׵gnu|~~(anonymous namespace)[abi:{default arg#}::JArrayauto:VTT for construction vtable for -in-typeinfo for typeinfo name for typeinfo fn for non-virtual thunk to covariant return thunk to java Class for guard variable for TLS init function for TLS wrapper function for reference temporary #hidden alias for non-transaction clone for _Sat _Accum_Fract, operatoroperator sZsP>(clqu : new java resource decltype (this{parm#global constructors keyed to global destructors keyed to {lambda()#{unnamed type# [clone restrict volatile const transaction_safe noexcept throwcomplex imaginary ::* __vector((......)decltype(auto)listring literaldt_GLOBAL_std::allocatorstd::basic_stringstd::stringstd::istreambasic_istreamstd::ostreambasic_ostreamstd::iostreambasic_iostreambooleanlong double__float128unsigned charunsigned intunsignedunsigned longunsigned __int128unsigned shortvoidwchar_tunsigned long longdecimal32decimal64decimal128halfchar16_tchar32_tdecltype(nullptr)aNaSaaalignof azconst_castcmcodVdelete[] dcdynamic_castdldelete dveOeofLfRflfrlSoperator"" mImLnew[]nwoRoopLpmrMrSrcreinterpret_castsizeof...static_castsizeof sztwthrow std::basic_string, std::allocator >std::basic_istream >std::basic_ostream >std::basic_iostream >#EgܺvT2%s: error: too many @-files encountered %s: error: @-file refers to a directory Cannot find prime bigger than %lu LMM)M@JMLLLLKLLKKKKKKKKKL%I$ <;G]tB{= 0$~`2fCOmA oE!a  0P AA ?  &*"@ `0PHX? "A!)?cccccccccccccccccccccccccccccccccccccccccccccccc ccccccc cccccccccccccccccccccccccc ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/tmpTMPDIRTEMPTMPCannot create temporary file in %s: %s /var/tmp/usr/tmp/tmpmemory exhaustedclosing pipeline input fileopen temporary filepipeline already completeopen error fileopen temporary output fileXXXXXXcould not create temporary fileboth ERRNAME and PEX_STDERR_TO_PIPE specified.PEX_STDERR_TO_PIPE used in the middle of pipelinevforkexecvdup2execvp: error trying to exec '': wait  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~CBBBBQ00000000000000000000000000000000 %s%sout of memory allocating %lu bytes after a total of %lu bytes undocumented error #%d-+ #0hlLOOâââOOOâ7â7ââstd::bad_allocSt9bad_alloc__gnu_cxx::__concurrence_lock_error__gnu_cxx::__concurrence_unlock_errorN9__gnu_cxx24__concurrence_lock_errorEN9__gnu_cxx26__concurrence_unlock_errorEstd::exceptionstd::bad_exceptionSt9exceptionSt13bad_exceptionN10__cxxabiv115__forced_unwindEN10__cxxabiv119__foreign_exceptionEt̩$pure virtual method called deleted virtual method called N10__cxxabiv120__si_class_type_infoESt9type_infoN10__cxxabiv117__class_type_infoEterminate called recursively ' what(): terminate called after throwing an instance of 'terminate called without an active exception iii``iixi`iixxxxiPPPPPPPPPPh(`PPp PCdddddddddddddddddddddddddd>dddddXdddd}| x @ ( @BB BBBBBBBBBpBP0BBBBBBBBBBBBBBBBBBBBBBBBBBBB==P` ` P HHHHSHHpPM9P4{X000P ))x)_)M*,00000000000000000000000000000000000000000002l332l33L0000l441l200000000L/00d1000000000000000000000000000000000000000000000000000000000000L600L55O4P\PlPOPP|POQRHSpSSS8TTTThUUU8VxVVV`WWXXXZ(YssssssssssssssssssssssQRY ayfyfayfaaaaaa a a@feeeehe8edyfadddddaaddadddddddddddxd`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`d`dddddddddddddddddddddddddddddddddcccccccccccccccccccccccccccccccc8cyfbyfayfxayfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfyfPbc dcccbbccbccc/db:dMd`dsdddfgPgffxg}h}}}}}~}};8E9LN,9V9] ;id;r;rD<t<t\=Nz=z >~> ?Z? (@3<@@|A^|E^}L^$}S^8}Z^L}a^`}h^t}o^}v^}}^}^}^}^}^~^~^(~^<~^P~^d~^x~^~^~^~^~^~^~^^_, _@_T_h_|%_,_3_:_A_H_O_V_]_0d_Dk_Xr_ly_____Ѐ___ _ _4_H_\_p_____ԁ__` `$`8`L!``(`t/`6`=`D`ĂK`؂R`Y```g`(n`<u`Pvcs̊xքNjPQ@Вʉ0lb:S0ƎX*6t|Jd\̛8vؗp 0D$բĝ(<Pdxȶ϶Ȟֶܞ۶,@Th8ԟ?FMR$Y8`Lg`nu|Ġؠ(<Pd÷xȷϷַȡݷ$T XĻ8BX|(BZܥ8n`f$$tP{YTpة^ ] iD\0̪=Kl"&*$@Pl,\lX4l8 Op^Z(2ܲ<a Xt8nгd<x &Hr(<hBܵ(*tض T @l`\@\">طH>pAj p<A Lܽ' E0Xu(d `:$F8RL^Dp\ HhT,H\#%)V../`r00p00 1PG2d2F3I:w::p:Y%@<0`t̘Ff ֙p.;(<P͜q3q4̞Pxڡ?},,\ݥ|e$<NtTŮDiձI,Xu16\30XVDl3?lu 4j8P.|67<l(`yF8dM`( TJpG,@ Luv|V&/0WTh[g<x z|>P6tqt"4" #''D4n5055(56 646\7p7X8LX9x::;; <<&< X< <4s>>'@ Y@<@ BxB8 CCC|oDDDDEOE8EhEF2F 9FX F F F G$ GX G 5G LG XG |G G\ I J J J JL J` K K K K $L .L QL(  Nt N tN N N >P0WQxcRS,S@STT4TnTTT2UH>U]4^r``4zaIv8vL4wLw$Tww1xDzlzZz{@{e$UP|ӁL|J Ńl~$ˆlYHmш$`tnj0`l ,ETpΛz <ȞP>d a â( 7T F F ` !I`!!!t("T"¨l"ը"""ѹ,#ut#>#R#o%c%4&&)&h'0'D'X'''?'(:T(h|(((-(1P)hd)))4*>d*+5D+|+p$,N,D-d-0 -q . h.4.(7t/7/s8<0N0Q0+R1>R1GR(1R<1R\1Rp1R1R1S1S1T1[T2T,2U@2XUT2U2BV2V2W3ZWD3WX30X3lX3X3/Y3kY3rZ4Z@4\h4\|4]4]45[,5v@555N5 6l66)6X7707D7%77N78,8d8X889/89*T9\9y9:׶P::L:B:˽ ;D;ƾX;p; ;H;\;;;<<T=h==W >4> `>=>2>(???h@F|@Z@\@p AAABHC_CDXD:lDGDPD]D3DlE EHEpE0EsEFF4GmHGn\GyGDHHH`HII0IIJKKvK $LdLLLLMMN8N0LN<`NGtNWOeO@PPP$QhQQgQR$R`RR1R9RtSS 8T,DVQx>R>S?TT@T@ U@]AL`lBjB|kpClCrCwDlxD EE\EHF F`GtJ@J|ATKLBL\BMlD`MEM,FN\>??T@ AA$ D`DtlEE@FLHI\IIPIJJKKK<KPKdL MHNN|OO( H A T E U E St:`qER A Td9EV A 8ARU AA sUGM(tqHAA aCB(HtxFAA jCB4t1LcAPt.QYA(ltFAA AB$euEAA AAuAE{,uBFK Gp AABHvFBB B(A0A8DP8A0A(B BBBHTxxtBBB B(A0I8JM8A0A(B BBByA4FBBD D(A0r(A ABB#^ET iFG~$(`EEA NAAP (dFAA AB8JFBB A(A0(A BBB$Ҁ(EGD UAAҀEEL 2BEE D(D0D@bH]PFHB@0A(A BBB(\tAC BQ\ * EZ(.!FNF AW4#BLA A(A0(A CBBE E C0(7NFAA DP= AAB4\QFBF K(H0(A ABB4gFHC DPF  CABA 'JX,JXƎ $ 8LL FBB B(A0A8D 8A0A(B BBBD H9^A\8{BNI A(G(A ABBl 4&FBB B(A0A8G"DBBBABBGGBBJAAQGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG G G G G G G G G G G \YN]A8A0A(B BBB$| x 2EDD bAA, FJK  ABA a, \ YAC HHJ A ),!x*E_(X!|eMAA RABy! ! !E A X5!p%E_! "t4"#NS`"ڵ4JXx"0Ej8"RFEI H(D0j(A BBBD"FBB B(A0A8D`8A0A(B BBB8#ųaIMB A(A0(A BBB8P#FBA A(D@(A ABB#X %(#t FAD AB ,X#$kFEB B(D0A8GKRF[ 8A0A(B BBBA $zRx <,60HHBNIGBN($AAG@} AAA zRx @ r FAE %FBE H(E0D8GpxIABBBapxxPAGGBSpF 8A0A(B BBBA  `%BEB B(A0A8B@ 8A0A(B BBBE  8A0A(B BBBA !U@&(@0&T*E_ U0H\&XFBB E(D0D8DP~ 8A0A(B BBBA (\#%. V 8K0H(B BBBE &&0&]' $'.8'-L')2D`'GBKE I(D0A8B@8A0A(B BBBH'eBEB B(A0A8GF8A0A(B BBBH'*BGB B(D0A8D`8G0A(B BBB`@(BFEB B(A0D8D@ 8D0C(I BBBE A8A0A(B BBBX(!FIE E(D0A8KlNRA]8D0A(B BBBD)zFIB I(A0C8A@u8C0A(B BBBH)2<\)BBE A(A0(E BBBL)h FGL B(A0A8G 8A0A(B BBBA $zRx ,H(*,FBB B(H0D8Fp 8D0A(B BBBA dONH*lBFI I(D0D8GPp 8A0A(B BBBA '=?H*%iBKE E(D0C8B@r 8A0A(B BBBA 4& H+%EGp AA zRx p 1+('4Hkx$f+<'l+! +'IK A c A \( l(,'FEE E(D0D8GPyXJ`KhBpIPL 8A0A(B BBBA I8F0A(B BBB(L)}w 8M0A(B BBBE ,kBHI E(D0A8D`FhLpShB` 8A0A(B BBBA BhLpGxAU`NhLpGxAU`NhIpGxA[`NhLpGxAU`NhLpGxAU`&@H-'{BBB B(A0A8F[ 8A0A(B BBBA $zRx ,`.|'FIE E(E0A8GP^ 8A0A(B BBBA  8I0A(B BBBC  +7.)&.,H.l"FBB B(A0A8DP 8A0A(B BBBA +H/|,8\/()FBK B(D0A8DIEAB^T 8A0A(B BBBA H|/H,FBB B(D0A8A@k 8D0A(B BBBA /<)//-(/)Od A u A g A jd,H00t*FBI B(D0E8K 8A0A(B BBBA $zRx ,,EBDAAb0KYX0H(1FIH ABl,1+iFBB B(A0A8B@P 8F0A(B BBBA gHLPBXD`BhGpL@JHLPMXD`BhBpI@JHLPMXD`BhBpI@JHLPMXD`BhBpI@JHLPMXD`BhBpI@JHLPMXD`BhBpI@JHLPMXD`BhBpI@JHLPMXD`BhBpI@JHLPMXD`BhBpI@KHLPMXD`BhBpI@KHLPMXD`BhBpI@KHLPMXD`BhBpI@KHLPMXD`BhBpI@ZHMPMXD`BhBpI@^HMPMXD`BhBpI@SHIPBXD`BhGpL@gHMPMXD`BhBpI@JHLPMXD`BhBpI@JHLPMXD`BhBpI@KHLPMXD`BhBpI@KHLPMXD`BhBpI@cHMPMXD`BhBpI@KHLPMXD`BhBpI@NHLPMXD`BhBpI@oHLPBXD`BhGpL@NHLPMXD`BhBpI@d.VHIPBXD`BhGpL@|HLPMXD`BhBpI@SHKPBXD`BhEpL@FHIPBXD`BhGpL@l4FBB B(A0D8GP`XI`BhBpBxBSPJXL`EhBpBxBSPKXL`EhBpBxBSPKXL`EhBpBxBSPKXL`EhBpBxBSPKXL`EhBpBxBSPJXL`EhBpBxBSPJXL`EhBpBxBSPJXL`EhBpBxBSPJXL`EhBpBxBSPJXL`EhBpBxBSPJXL`EhBpBxBSPJXL`EhBpBxBSPJXL`EhBpBxBSPJXL`EhBpBxBSPJXL`EhBpBxBSPKXL`EhBpBxBSPKXL`EhBpBxBSPKXL`EhBpBxBSPOXL`EhBpBxBSPOXI`BhBpBxBSPNXL`EhBpBxBSPOXI`BhBpBxBSPJXL`EhBpBxBSPLXI`BhBpBxBSPD8C0A(B BBBt6,6,6,<6,&FED D(E0E (F ABBA p8N@BHDPGXG`L0K8L@HHDPEXE`N0J8O@EHDPEXG`L0J8N@KHDPEXJ`L0J8L@MHDPGXG`I0J8N@HHDPGXH`I0J8M@EHDPEXJ`K0J8L@GHDPEXH`L0J8N@HHDPGXJ`I0K8N@HHDPGXG`L0K8L@HHDPEXE`N0K8L@NHDPEXG`L0K8N@EHDPEXJ`L0J8L@MHDPGXG`I0J8N@HHDPGXH`I0J8M@EHDPEXJ`K0J8O@GHGPIXH`L0J8N@HHDPGXJ`I0J8N@HHDPGXG`L0J8L@HHDPEXE`N0J8O@EHDPEXG`L0J8N@EHDPEXJ`L0J8L@MHDPGXG`I0K8N@HHDPGXH`I0K8M@EHDPEXJ`K0K8L@GHDPEXH`L0K8N@HHDPGXJ`I0J8N@HHDPGXG`L0J8L@HHDPEXE`N0J8O@EHDPEXG`L0J8N@EHDPEXJ`L0J8L@MHDPGXG`I0J8N@HHDPGXH`I0J8M@EHDPEXJ`K0J8L@GHDPEXH`L0J8O@JHGPKXJ`I0J8L@MHJPGXE`I0K8M@HHGPIXJ`K0K8N@EHDPGXH`L0K8N@EHDPEXJ`L0K8L@MHDPGXG`I0J8L@HHDPEXE`N0J8O@EHDPEXI`L0J8L@MHDPEXH`L0J8N@HHDPGXJ`I0N8L@MHDPGXE`I0k8I@BHDPEXG`L0A8I@KHDPEXE`L0P8K@BHDPGXG`L0O8L@HHDPEXE`N0S8I@BHDPEXG`L0f8L@EHDPEXE`N0`8O@BHDPEXG`L0`8N@BHDPEXJ`L0`8N@HHDPGXG`I0`8L@EHDPEXE`N0`8O@BHDPEXG`L0`8N@BHDPEXJ`L0`8N@HHDPGXG`I0_8N@HHDPGXH`I0^8M@EHDPEXJ`K0*Q[8N@HHDPGXH`I0T8N@BHDPEXH`L0G8N@BHDPGXG`I0\8O@GHGPIXH`L0v8N@HHDPGXJ`I0S8N@BHDPGXJ`I0T8K@BHDPEXJ`L0F8D@BHDPEXJ`K0F8N@HHDPGXJ`I0F8N@HHDPGXG`L0G8L@HHDPEXE`N0<6j=\=7FED D(E0y (F ABBA q8K@BHDPEXJ`L0K8L@MHJPGXG`I0K8L@HHDPEXE`N0J8O@EHDPGXH`K0J8L@MHDPEXH`L0J8N@HHDPGXJ`I0J8L@MHDPGXE`I0J8L@EHDPEXL`L0J8O@EHDPEXG`L0J8N@EHDPEXJ`L0J8L@MHJPGXG`I0J8L@HHDPEXE`N0K8O@EHDPGXH`K0K8L@GHDPEXH`L0K8N@HHDPGXJ`I0K8L@MHDPGXE`I0J8L@LHDPEXJ`K0J8N@EHDPGXH`L0J8N@EHDPEXJ`L0J8L@MHDPGXG`I0J8L@HHDPEXE`N0J8O@EHDPEXI`L0J8L@GHDPEXH`L0J8N@HHDPGXJ`I0J8L@MHDPGXE`I0J8M@EHDPEXJ`K0K8N@EHDPGXH`L0K8N@EHDPEXJ`L0K8L@MHDPGXG`I0K8L@HHDPEXE`N0J8O@EHDPEXI`L0J8L@GHDPEXH`L0J8N@HHDPGXJ`I0J8L@MHDPGXE`I0J8M@EHDPEXJ`K0J8N@EHDPGXH`L0J8N@EHDPEXJ`L0J8L@MHDPGXG`I0J8L@HHDPEXE`N0J8O@EHDPEXI`L0K8O@GHGPIXH`L0K8N@KHGPGXJ`I0K8O@JHJPKXE`I0K8M@EHDPEXJ`K0J8N@EHDPGXH`L0J8N@EHDPEXJ`L0J8L@MHDPGXG`I0J8L@HHDPEXE`N0J8L@NHDPEXG`L0J8N@EHDPGXH`L0N8N@HHDPGXJ`I0l8O@BHDPEXG`L0`8N@BHDPEXJ`L0`8N@HHDPGXG`I0`8L@EHDPEXE`N0`8O@BHDPEXG`L0`8N@BHDPEXJ`L0`8N@HHDPGXG`I0`8L@EHDPEXE`N0`8O@EHDPGXH`K0P8F@BHDPEXL`L0N8O@EHDPEXG`L0T8N@BHDPEXH`L0^8L@HHDPEXE`N0S8K@BHDPEXJ`L0S8N@BHDPGXJ`I0S8K@BHDPGXJ`I012Hk8O@EHDPEXG`L0]8M@HHGPIXJ`K0h8L@MHDPGXG`I0F8F@BHDPEXE`N0G8K@BHDPGXE`I0G8L@GHDPEXH`L0G8N@EHDPGXJ`L0S8N@BHDPGXE`I0CCCCCCCBCnCaDTDG,D:@D-TD hD|DDDDDDDEE0EDEXEwlEjE]EPECE6E)EE F F4FHF\FpFFFFFFFsFfGY$GL8G?LG2`G%tGG GGGGGHH(HFLB D(C0(A BBB$`[sEHG0\AA0[fFLD C( ABB[Z`AN LD8[FLB D(C0(A BBB$\sEHG0\AA`@\ FBB B(A0A8GP 8A0A(B BBBE D8A0A(B BBB8\FFGD C(E0&(A ABBD\FEE E(E0G8GP8A0A(B BBB`(]JFBB B(A0A8GP 8A0A(B BBBE D8A0A(B BBB8]}FGD C(E0](A ABB`]BFBB B(D0A8DPm 8A0A(B BBBE D8A0A(B BBB8,^FFGD C(E0&(A ABB`h^FBB B(A0A8GPs 8A0A(B BBBE D8A0A(B BBB8^}FGD C(E0](A ABB4_ FBA G(D@(D ABB<@_6FEE D(E0J@0A(A BBB,_FID G@ AAB4_xFBA G(D@(D ABB@_HhFEE D(D0L@w0A(A BBB ,`h^RH G L A YHd``],E[8|`X+<FBI A(I0(E BBB(`\,EDD I AAA (`,EDD F AAA La$-FBA D(A0/ (I ABBE H (A ABBA `aPtaB`AN LD0a`.FBB B(A0A8D`(@[Nm 8A0A(B BBBA Ha^bFBB B(A0A8D` 8C0A(B BBBA [nTbq8lbX.,bd.FAA U FBA _Mb/ bb.cd`c`` (c\`^FEE E(D0D8J`,8A0A(B BBBH}?FBB B(D0D8D`b8A0A(B BBB}ZGEU(~@+JEG QAAA4~@/NX4L~@FAA m ABE AAB8~2AFBE J(A0j(A BBBD~FFBB E(A0A8A@8C0A(B BBBD8GFBB E(A0A8A@8C0A(B BBBHP@(FEE E(A0D8G`8A0A(B BBBHBDFED C(D0L (N ABBE A(C ABB`BFBE B(A0A8G 8D0I(B BBBE [8A0A(B BBB<LNE``0N FBB B(D0A8G 8A0A(B BBBA xMGBK$zRx ,)E) HTNeFBB B(G0A8G@ 8A0A(B BBBI (}Q 8J0A(B BBBE ̂P S8PFBA D(G@u (A ABBA zRx @$SGHd QFBB B(A0A8D@M 8A0A(B BBBA ~S7$ă91EDD aAA<9FBB A(A0D@0A(A BBB$\uRD\ 0D(A BBBE $T9HEDA {AAHuR: EZ:7^MȄ,:4Ej$P2ADA iAAu1R P8ErR(P9SLAD s AAE $|::EDC aDDH0:BBB B(D0A8Dp{ 8A0A(B BBBA s}QQp:,Eb( OMFDD {AB|rQn`D:tP:ETT:(`:EDJ AAA $І$;+EAD ^AA,;EUH OFEB B(A0F8I} 8A0A(B BBBA YPtO!((TEDJAA$pO@EAD sAAxT,T:"KUA h:EU(TEQDT 8XTFIE A(D0(D BBB6U)EXCU(ĈAU,FAD ]ABDAUBBI E(D0D8A@8A0A(B BBB8U8EgTV hV |U (bU8FAC jAB8E U-$UEH BL XV,Ef 4`9CEK i DA HX MBEB E(D0D8F 8A0A(B BBBA @9QEM A r4Ċ9}FLM A(A0U(A ABB(XCEDD R AAA 8(M FEA D(Lp (A ABBA d`9VH H A H9HFBB B(A0A8Dp 8A0A(B BBBA yTj8TNBBA A(A0R (D ABBA zU80D=WBLA A(Dp (A ABBA zRx p$~U 4>cAa N!$̌x>AAD AA}6UH|N&FBB B(D0D8DPK 8A0A(B BBBA T>SE_ A Z E T (hM^FDA |IFM0EW A NH؍l>[FBB B(A0A8D` 8A0A(B BBBA T8l?*Ed(P?DFIH iAB|?*E`UCEK nD(UDBFM gABDUBIQ E(D0F8E@@8I0A(B BBB,VEzHV6\V(EbxV0VFFA D AAB(P[FAA ABX?\|FPH B(A0A8DNeA8A0A(B BBBDHeFBB E(A0A8A@8C0A(B BBBD,fFBB E(A0A8A@8C0A(B BBBHؐ_FBB B(A0A8G8A0A(B BBB$Zd`AN LDDVfTEx U AdPK)x|,XK)Nf $Ff#EAD VAAܑ= H=%FBE L(A0D8D 8A0A(B BBBA tde,P=AC BJHDY A \yfv0fEHD e AAE AAA8Ȓ>FBA A(G` (A ABBA Hf~8\@}FRA A(G8o@f(A ABB\T@BEE B(G0D8G  8A0A(B BBBA jL|A$zRx ,fHamm.$HCEDG0pAAP_m,HTHBEB B(D0A8GPm 8A0A(B BBBA T+mO`IHE I\ДdIlFBE E(A0D8DQJPA 8A0A(B BBBA dlgD`KHXlKBEE B(A0A8G 8A0A(B BBBA TmS0KFAA D0  AABA zRx 0$m+H m@FEE B(A0D8D`b@8A0A(B BBB0lKDHBA A(g  ABBA zRx ($ǭJ$ԖAFD0AAHVFEE E(D0G8D`'8A0A(B BBB(\8LEDFP AAA ,yV(XDE sAAA(ȗ'FIA ABHFEB G(F0D8IpU8A0A(B BBBT+h3|<+J`L $DAEDD qAA4Ԙ^MFED C(C0q(A ABBP sFHH E(D0A8J`ShBpFhA`r8A0A(B BBB(`EF BKJ $fIEGD vAA(̙xJ<FDH fABJ0E*HK5BEE E(D0A8B@ 8D0A(B BBBA `tL 0BFDC G0  AABA K $К4LSEJG sGAċAAA,CEC FF A  ӳX`XLIBBB E(H0D8GP 8A0A(B BBBA R 8G0C(D GBBE pp$ЛtKEAG AA(ČW ICE Y ICE $$K[ACD PAA9`K3AqĘ TKFIB A(D0D@^ 0A(A BBBA R 0G(C DGBE X2LHLjFBB E(A0A8J 8A0A(B BBBF ds&_`J0tJBDA G@  AABA zRx @$ HܝhJBBE E(D0D8D` 8D0A(B BBBA S(,<xNDNCG X AAA P87"THA8|NFBA A(G@ (A ABBA <؞Epd5[EQ$tECG0AA(KEC HH2 Ԧ.H(WFGB B(A0A8G`28A0A(B BBB$43>]DG SAA,\IFID D0 AABEM  YS(ԧRgAC FJR $QECD BAA((.EC I T 4laFED D(E0i(G QDB8FED D(G(A ABBDqBBB B(A0A8B@D8V0A(B BBBH(BEE E(D0A8J8A0A(B BBBHt:BBB B(A0A8G8A0A(B BBBKܩjKKK(0AKGFA\(\KGFA\(YKGFA\(KGFA\yK4RFEA C(D0`(S CBB(4`GOFAD yHB`JFBB E(A0A8GDDDDDh 8A0A(B BBBA GKAM GGGHMVA$zRx d,.MGLBGGGVGGGYqGGGYGGG~dGuB3GGGGGXGGGU{GGGTPRAMPAMSAGGGDGGGK{GGGKEJGGKX`FBB B(A0A8D` 8D0A(B BBBD hMpXhB`Dl5dhNpThA`hOpVhB`hMpThA`hLpUhA`L<hFHE E(D0A8G[ 8D0A(B BBBD <DDQP&DȮ|DBBB B(A0A82 0A(B BBBA zRx 8(THFBBB G(A0Dp  0A(A BBBA WxPGGqp zRx p4(FQxJGGqpQxPGGqp@IBAA GPXD`DhDpIPD  AABA zRx P$tIShJdJİ`Jذ?JeH;BEB E(A0A8GP8D0A(B BBB`J5tJ-JNı رJ{- 8!FKK K(K0(A BBBPn?d(|xJFQO ABK`LgFBB E(A0A8I/ 8A0A(B BBBA $zRx ,^HLnAJ A {BA|JX^yJLJFBB B(A0A8Dy 8A0A(B BBBA PlTLxQBB B(A0A8DPXK`TXAPn 8A0A(B BBBA UAP4TPMFBE E(D0D8D@bHLPUHA@M 8A0A(B BBBA $HMBBA A(B0z (D ABBA s (D ABBB ,mN (J ABBE 8pNBEB G(A0z (D BBBA HNLԵ$wtEAD gAA'Aa,xN@NTkHNldN(E\ A \qBBE B(A0A8B@ 8D0A(B BBBE A8A0A(B BBBDBBE B(G0A8GP8D0A(B BBBDMM4Xw@FDD Q(K0F(A HDBETPwAMķ 0طM1FDB B(A0A8DP(L 8A0A(B BBBA 8NL,Eb(hOAA aFAADZBIE B(A0H8DP8D0A(B BBBܸ(AC HH Y $0X NEGD xAD(X~ rFGC [AE *HX I EG0A4 FFD S(J0O(A EAB   4 H \ p (PL=EAD 0AA| BĺPMغ\ME< ) -NY$ 8 -Eg8TpMmMEE D(A0I(A BBBO4PPFAD M(N0^(A l ABA  + $PoEDD _AA +aDA84 sFBA A(D0( (D ABBE 8pPFBA A(A0I (A ABBA  B(4QyECD  AAA  c KAE ( hRFAA ABh L ` (AC A"  *HFHE I(D0A8A@8A0A(B BBB =LR9Es\o $(\R/EDG \AAPcNEH#$4R-EAD `AAtjX Hоc9FBE B(A0A8DP 8A0A(B BBBE лq(0gZADG0f AAA L\gFBB B(A0A8G 8A0A(B BBBJ  BPALпyFBB B(A0D8D 8A0A(B BBBE бFnH4pBHE E(H0A8Dp 8A0A(B BBBD pTxJ[xAp@BEE A(D0D@T 0A(A BBBA !qHHPQHA@P!LIA A(B0c 8B@B A8I@T8D0A(A ABBHX܊hBHI B(D0D8Dp 8A0A(B BBBG !;YxJPxAp(EEAD \ AAA (EAA q AAA }"0DDh"HXFBB B(A0A8G`0 8C0A(B BBBA , "y hGpMhM`hDpLhH`.QQA8:&2HFPP E(D0A8DPa 8A0A(B BBBA  &IXP`KXMPHpBBB F(A0A8DPq 8C0A(B BBBA p!'<MFBB A(C0k (D BBBA *!L$КBHB B(A0A8J 8A0A(B BBBA |Z* 4@BED C(G0d(A ABBH$PBB B(A0D8D@L 8D0A(B BBBA  6( tqJAD UAAJLhL;c`67t>(̟kE E n A Y E 6Y$,LHADA AA,TLgFKA B ABA 4 LKFBD D(C0n(D ABB86lL L(LEP A d A ^ A iX6.@-FBB D(D0DP 0A(A BBBA zRx P( 6lPLNdN6xLf=68a7 NnXB A TN~$NEDA sAA O; 7_D40O BBB B(A0A8B@I8A0A(B BBB(|7Z 8F0A(B BBBE 7h,9;S9TX9M:$KU :(: <:2P0:>dZ:6x|:eX$:EEK AA; 4;FDA f ABE LABH <+FBE E(A0C8DP8D0A(B BBBP<2El8l=BEE D(D0\(E FBB(>u\ED LAB-=1H ($LFOHK aAAHL;FEE E(A0A8GP 8D0A(B BBBA @>|OH r A (V~\DD _ ABA H0FBB E(A0C8G@ 8A0A(B BBBF $>$O8>(LEAD l AAA 0x,FGH NP  AABA pF>ģ>(NEDGPt AAA hb>54<O6FBE C(D0W(A ABBTv>>,(HHDFEB E(A0D8FP 8D0A(B BBBE ,>OĦ@$Ц?FAI G0  AABA   CABA 8>K|O{ A \*>=0aA^ AG kXzRx  >AM($0NBDD m ABA PTd`@x&02>HHA D(c DBB,> @x>$TNGF AA X>M,>FDD Kpg AAB> $>(EDD JIC>*>EH |($? <?#EVHX!?FBE E(D0I8A@8A0A(B BBB@$@UEDA HAA@ @%IUDL@FBL K(J0KpxONxDp0I(A BBBD`BFDD L08H@CHBPAXE`I0Y AABDB FHB B(A0A8 0D(F FFBQ TC.OEE A(D0 (A BBBE Y(A BBBAH,L\^D pTD 4LDjFFA C(D0O(A ABB~D!WH$D:EDD jAA,DcMHA HABA,D4@DOFDA i ABE ICBxD dȨ FBE B(D0A8D` 8A0A(B BBBC  8A0A(B BBBA lrDX<}FBB B(A0A8G`t 8A0A(B BBBE JhBpzhA`KXxLBBE B(A0C8Gp 8A0A(B BBBA kxB@xApM,JV{NsWJN8(FBA D(G@ (A ABBA 8VNpxXFBE B(D0A8Gp 8A0A(B BBBC ~xE}xApdb,I>dDIzdDE~H$IFBB B(D0A8DP` 8A0A(B BBBA Vd@,@JAC BJ A LReO@PLXFBB D(A0GP 0A(A BBBA Ie|DhBDJ B(H0D8Hp8A0A(B BBB,$inVAA GFBA(TicFDC RAB(iFFKD gGBj8;j(Oj HL(TL^FDC MAB\j 8@tL9BBA A(D0T (A ABBA \ik$dLIEC Ir A zRx  (i(TLUEAD j AAA LA A 6j{HP4MJFEE H(D0A8DP8A0A(B BBB(PQjq 8I0A(B BBBE ( NFDF oAB$j6Hj;FHB J(I0A8Dp8A0A(B BBBDTkFMF B(A0A8LP8A0A(B BBB$WlEAD zDA<lFBB D(A0(A BBB$`MeEMF JAAH,FBE E(A0D8Dp 8D0A(B BBBH hlVHXjFEE E(A0D8Dp| 8D0A(B BBBI l:l*E`HL0FBE E(D0A8A@ 8A0A(B BBBA 8TlIFEE D(D0i(A BBBDlZFEE B(E0D8A@s8A0A(B BBBHlSFDB E(D0D8F` 8D0H(D BBBE 8$oFBB D(A0(A BBB,`^qb\AD |ABA(qtBGH _ABLKFEB B(A0A8J  8A0A(B BBBA q 8 |BBB D(D0(A BBB$\|ZAHD JAA|@Ez }IB}5c}w8}BBE A(D0(E BBB~rWY80xBBE D(A0U(G EBBl?EpvLZFBB B(D0A8G`78A0A(B BBB܀rEO`\A.EG A$EI`ADEb(XtFDD bABDۂFBE B(D0D8E@8D0A(B BBBDFBB B(D0D8DP8A0A(B BBBZ(`;EuHDBBE E(A0A8G8A0A(B BBBHXFHH D(D0f (A BBBB A(C BBB<RFHH D(D0l(A BBB8FEE D(D0a(A BBB(XD6EDD fAANHONMHQBLJ B(A0A8Ib8A0A(B BBBHR BBB F(D0D8D/ 8A0A(B BBBD\BBB B(A0A8B@8A0A(B BBB H C L C HBBB B(E0E8D8A0A(B BBBfBEB B(A0D8JhZJBGTRAX\NB}JRBJPAPNBJPBSKAeLKBJHD D G N5NSAHMZAFPTHwXOBGBD D G NVRBDKA{GAN G G G G G G q8A0A(B BBBDϫFDA G@yHEPBXF`HhFpM@| AABP{FEJ E(G0D8GPXXV`YXAPR8A0A(B BBBddFBB B(H0G8JcBGGGa8A0A(B BBBDޭFBB E(D0D8GP~8A0A(B BBB4=?EGD f AAC AAALD<`l&t~,BAA D0 CAB(rAPJTAA$>EAAA AA8 [BEE A(C0q(A BBB8HrBBE D(C0Z(A BBB$ޯ.AFD `AA$+AFD ]AA$>AFD pAA\AX E }`9BEE B(D0G8DPn 8D0A(B BBBE \8A0A(B BBBٳ74UBED D(E0v(A ABBPBDB B(A0A8B@HDPFHA@i8A0A(B BBB D@X8$ BBE E(A0A8G"DKA8A0A(B BBBҶiBBB B(A0A8GDPAJGGXVGGGXrBBBJGml8A0A(B BBB88BBB A(A0~(A BBB4tBEA E(H@(C ABBYBBE B(D0A8GDTBITAIHPAyJBB]hDBB]8A0A(B BBBTDBBB B(A0C8G M[BDdBI]AGDD]`8A0A(B BBB\FEE E(D0D8D`ehJpThB`khKpThA`z8A0A(B BBBDL BEE E(D0D8E@[8A0A(B BBBd\hFEB E(A0A8GABBJG`$8A0A(B BBBL\AFBE E(D0D8DP8A0A(B BBBHLMOHEE H(D0J8K@8D0A(B BBBHP(BHB B(A0A8G'8A0A(B BBB,=AF M} A KT( @NFHE A(H0TDGBIk 0A(A BBBA zRx $(cBBBBIXBBF B(A0A8Dp0xGPxApi 8C0A(B BBBA ,<(AF P F H/cHBBB B(A0A8Dp 8A0A(B BBBA 204BAA G0  AABA  UI0#!D"! X!<l?!$HA B(J0NC! 8!EIB N7! ,!6EpJ!hA!@He B(B0I("TJE@C"FE@\m"qp"F4"kBID D(D0M(A ABB4/#BBE D(D0g(A ABB$v#fAMDPQAA(#_GAA RAAA(H#SFDD AABt$p$j$fNFJAA$<Az$TMCA %oAAkA K%<Az(k%A(DV&JBAD AB$pt&nOAA(BJ(F$|(ADD AAH(!BBB B(A0A8J!8A0A(B BBB$4JAAG@AA\'KDp.KBDD  ABE  ABE AABHOBEL B(D0D8E@8A0A(B BBBHrQBEB E(D0H8E@h8A0A(B BBBHPS BBE E(A0A8E@8A0A(B BBB4yUBED A(D0(A ABBL9VDRBE B(A0A8B@8A0A(B BBBA$-X/8HX/LcX/`~X/@tX@ FBB A(A0G@$ 0A(A BBB$bAAG0AA0;c[AAE y JFE ACAbcQNA(0c]AAA WAA4\dBAA ~ ABE DABH"hBBB B(A0A8GP8A0A(B BBB4l*BAA  ABE DAB$rjCD AA$@sAJ BD htRAHu2BBA A(G@| (J ABBE (A ABBvLv\BA A(E0F (D ABBE A(D ABBH4{BBA A(G@@ (J ABBE r(A ABBH|BBE E(D0A8GP8D0A(B BBB ~EO C (AC BID NAQ@uA4<FKD A(G`(A ABBt5Ef:H q }?H vJH AփKH B@( "FHJ B(A0C80A(B BBBHl4FBB B(D0D8GPQ 8A0A(B BBBA lz(4EDG0 AAA  L 5FBB B(A0A8G L" 8A0A(B BBBA $zRx ",65;H r(XwEDGdAAHH5FEE B(D0A8Gx 8A0A(B BBBA $zRx ,/R(dmbFAA VAB(2KDD UDAHFBB B(A0A8G`8D0A(B BBBLROBB I(K0D8D@t8A0A(B BBBAX,lh4EEAJ- AAA 5Z5H` A h6K A AEJA4 ݇UFAD J; AABD X6 (l6IFAA zDB0ˆEF6$E^6LEBA 6$E^(\<\$E^\6HB Lx6"HF SD6FEB E(A0D8GP8A0A(B BBB#$7PANׇ( H7'FDD TAB$H L7"EDG CIAp -H @7FBE E(A0C8GPY 8D0A(B BBBA ,%D 8FGB B(H0C8DP8D0A(B BBBH, x9zBBB E(A0A8A@a8A0A(B BBBxf :4 $;hFJD D(A0H(A ABB( \;XFAD Z HBB $4)S LBC AAB, x>@ p0T @;UFAA G0|  AABA u. Ƈ     D FEB B(A0D8D`8D0A(B BBB ;94 `"HF S$P f7EAD jAA$x uEDG CIA$ lLEAA BAA4 CFED A(A0k(A ABB   9, 9@ {9T 9$l 9cEG I G AA  : ,  :AC Id A  hH x1JDD UDAx <@cNBB A(D05 (A BBBA d0\SHA AAAH ,=#0@>BAF G0m  AABA y 0L>FAD G0x  AABA yi4>FBA A(D0(A ABB0Pl-EAO8}*L'`$tEHG@AAFHB E(A0C8GHIDEBIG 8A0A(B BBBA JGDHEI\h8<@FHB B(A0C8GJGDEBLJ 8A0A(B BBBA pFBB B(D0D8Gp 8A0A(B BBBA qxPExBpYxEDxAp[xEDxBp͎T,BBB B(A0A8DPg 8D0A(B BBBA oXE`NXBP( EAG@ DAE  DAE HAAE S CAE  DAE A FCE DAA4FBA A(A0(D ABB<TFBB A(A0D@0A(A BBB$ECG@AA6+URA0EFDD F@ AAB h $;$(4PFAIp CBB zRx p A$*BED C(G0@ FBE D(C0J] 0A(A BBBA zRx (k4 H͓1Ec E Chޓ|ܓ ԓ ˓9eEG0WA <gFBB D(A0 (A BBBF <09BEB A(A0 (A BBBA HptFBE B(D0A8GP 8A0A(B BBBA pÒ4:8@:FBA A(D0g (A ABBC mV4 H\:ps,:MKDD Y AAA [7,:KKDD d AAA ND :FBE B(G0A8FPh8C0A(B BBB,h:sFAD H ABA ~ x$anEDG@[AA(rEDDPbAA(:|EAL@b AAA tTƑL l3ES A T A  (IEAD ^ AAA  sp:'VO:4Ed A `A,5uEAF ,Lx:BFGD mAB$|:/EHA ^AA2/Ei$A.EDA aAA,X:4FDD bABHh:FFB B(A0H8KpA 8A0A(B BBBA X ː!|; ; ; ;dE] F ; ; ;$;EQD; \; p; ;;;)LX;)LX<8EAIzPLRxy" ,$< AAG  AAJ zPLRx)"  (w ,8='o AAG  DAF pW  >1TT H>b4 EG D >5 dI0>gHA G P?5`IhܟyHX A ? ?? ? ?EQ?EQ ? ?EQ<?P?EQl?? ? ? 0?BDG G0a  AABA T?EOHaJ F `( l@D _ E HD ABED A(G@\ (A ABBA D(C ABB DANI8 |ABGD A(G0 (A ABBC L@BOFBB B(A0A8G 8A0A(B BBBC ,zPLRxE" 4 0hGOFBB A(A0Gp(zPLRx" p0@GEADzPLRxe" $ _L"G`"Gt"GEAD"GEAD"G"$G" GEAD " G;Eb I A A # 2d \ d@ p    ` ʹ  ع   (@  x  d 3 8  H 8 @X L  h  w H d Kd P Ѻ d P   ( ` +  I (d ` d } 2 ( h ƻ  ޻  '   @ 2 p B  @ ] d8 s  @ @Ƽ ܼ  x @ .  L  ` d8 y '  d0 X   X (d  ѽ 3h  d  0W 2  P p ' P  i H  8 X  ¾ ھ 2 @  x $  > H p T i x  (d@ d ʿ  ܿ @ 0  a8 "  1 ' C @B@  U  h @ ~   @0 x  ' #  < 2?B@ O Z x     ( X  X ( X  d(    3 d?B M   c d?B } ?Bp 2?B  P 2 d   c`   h (  ( P 2p 0 J  ` dX w   8  :6   ( @>v X / 8  C F J B  G S `Y d @s G ~ N   < L@  N N @  {X  h      @ V i ` 0  2 2 2 2 #2 )2 ,2 22 )2 ;2 F2 T2 _2 m2 FC m2 2 w2 2 2 2 2 FC 2 2 2 2 2 2 2 2 2  5 %5  w45 0;5  F5 O5 kpk5 O5 kp@u5 m p5 np5 5  5 z 5 5 o p5 5 op@5 v p5 x6 x` 6  6 !6 )6 H26 "C6 S6 Hd6  q6  H6  6  HWC 6 ( 6 8 h6 6 06 6  0@6 6 06 2 sw7 7 sw37 7 pM7 7 p@h7 7 sw@}7 p7 p@7 07 07 0@7 0 8 0@*8 0@A8 6  0@L8  W8  Hc8 uw8 uH8 a8 b8 p8 gw8 i8 $9  0 9  '9 6 jp09  0>9 6 jxhH9 У P9 =`Y9 lk9 Q 0 v9 n 9 p9 q9 l9 lH9 p p9 s9 sH9 t8 y p9 u : v: w8: xJ: z\: zHo: {: |` }: k :  : : : H: :  :  : ]:  H^C :  (; ; rp+;  9; 0K;  0W; 5 ph; 5 p@z; zp; p(MC (; 6 wp ; 6 {p ; O5 p; #K ; p; p; 0 5 pfG p(C 7 0; p; 7 ; X @C ; ; p< 6 p < 6 p< p!<  p%< @ 6 p *< p p.< p2< p6< 2  d9< @ $@< $D< $H< pK< N< R< V< Y< \< _< e< Hl< s< H{< < H< < 5 p2  "< H< @ 0,<  0< 0B< X 04< "8 "<< 0  @@< h @D< /U `   = ث  BH*= = >= 8 0BPX= Ь  0Xe= n= 0\= 0B`=  @d= @h= 8  "l= 8 bl= h @p= t> "x> @  "x$> p |8> E> `  0I>  0BW>  0f> X 0 0w> 0> @  >  >  >  > 8  >  > @> ز  ? ? h  ")? h "=? 0R? س  0^?  aFF l?   B{? @ 0? p @? 0?  ? (  0? p 0? ?  0? ص @@  @ P  p,@ @?@  Q@ "e@ ( 0"k@ X  @ @ 0@  p@ ȷ @  @ 8  A  0 A ȸ "(A  :A ` "RA oA ع  A   0$A H  @(A 0,A 0A  04A P 08A  <B Ȼ  0@B  0DB 0  0H-B 5B 0 L` SB $2 ؼ `qB 0PB ( p"TB X  XB  \B 0`B   0dB H aFF0B 0hB Ⱦ 0lC  0pC H aFF0&C ȿ 0Bt9C 0 0xKC p 0|_C aFF0sC  0BC `  0C 0C H 0BC 0C  bC p "C @ D @"D "(D ( 09D X 0ND 0cD  nD F"D b D P  D  @D  @D  0D  D @   E  0"E "+E  0H  0BxH  @"|H p A"H B H CH ( D I `  EpI  F"#I G08I 0 H MI ` I]I JzI HI L"I  M0I X N0I O"I  P0I   Qp"I P aFFSR I P  BI T  J U0J V0-J 8  W@Y  @Y h  @Y  @@ Y  B$Y P  C@Y p  D$Y E$Y 8 F Z G$!Z  H$4Z P @FZ x @\Z  K lZ   L {Z   `Z x N$Z   O0Z  `Z ( Q Z h R@Z  S@Z   T@Z   U@ Z @ V@[ p W [  X ,[ @ Y@?[ 8 Z P[  [@ d[  \@$v[  ]@([ ( ^@,[ `  _$0[  `$4[  a$8[  b$<[ 0  c$@[ ` d D\  e$H1\ ^ E\ gf K\  hL`\ ( h P`  i T}\  j X\  `\ p l \  m `\ \ n0\ 8  `]   p@d]  q0+]  r$h1]  `9] H s0lI]  s0p^] s v@j] sG  s`x}]  sy@] P sz@] x s`]  s| G  s } ] P zs~@] ] s  ^  s $^  s <^ 0  M^ ^^ $v^  ^ `   ^ 8      (  ^ X  ^  0^  0@_ ( 0!_ x `+_   >_ p  O_ \_  $w_  ` _ X 0@_  $_   _  0_   _ @` p  ` ` @<`  $H`  Z` `m` (! $` X! `` !  @` ! @@` " @` X"  $` "   ` 8   ` " $` #  d a `# $'a #  @@6a #  @@Ba 8$  @Na h$ @@ba $ @za $  0a (%  a `% @a % @ a %  $a %  a & $a H& $ b &  $ b ' $$b P' $()b 2b ,Ib ' ` [b (   0jb @(  4xb p(  8b (   <b (  @b )  @b X) Db ) Hb ) Lb * @Pc h* @Xc *  @*c *  @9c 0+  @Gc `+  @Tc + @oc +  $`zc (, $dc X, $hc p  c ,  c (c hc , $lc p   c 0- d T p   d d  p:d X- $tJd - $x[d -  |od .  d P. @d .  d d $d .  d / @@ e X/  @e / @@)e / @;e 0 @@Ke X0  @@Xe 0 $ae 0 $re @1 $1 1 $e `e 1 `e @2 @@e 2 $e 2 0@e H3  3 3 (` 4 P4 ,`e 4 @f 4 @,f 4 @@Ff 5  $Sf P5 $\f 8  of 5  $~f 5 $f 6 $f @6 $f  f p6  $f 6 $f 6 $f 6 $f 07 $g h7 $g  "g 7 $,g 7 d=g 8 $Rg P8 $fg 8  dtg 8 $ g 9 $ g 89  ` 9 9 " $ : : $ $ g ; @ g <  $ g 8<  $ g $ g x< $ h <  ( !h <  , 6h (=  0 Nh p   Zh p= 04 sh =  8 h >  $< h d< h $@ h > HD h h $h > dH i ? $L i ?  P &i X@ "  3i   Bi @ !$T Ui @ "$X ji 8 # zi i $$\ i X@ "% i @ &$` i A  '$d i 8A ( i XA `h j A * l j A `p (j B  , t 5j XB - x Fj B ` Mj B / Vj (C 0@ lj pC 0@j C  2$ j D @@ j hD  ` j D @@j D @@ j @E @@ j E  8  k E 9  k E :  /k F ;  Ak `F <  Wk F `ik G >@ zk XG  ?$ k G @$ k G A$ k H B0 k p C0k p  D0k p  E0k p F @ l p G l HH H  *l H I  =l H  4Ll I K \l PI L$ rl M  l p N l I  O  l I @ l J Q l J R l J S l J T m 8K U m K V *m K W ;m L  ` Jm XL L  YhUm L Z$ jm tm [p m M  \p@ m 0M ]p m `M  ^p$ m M _ m M  `$( m M  `m b m 0N c$, n `N d$0 n 8 e 'n N  f@4 6n N  g$8 Dn N  dSn fn i$< n @O jdn pO k @ n  l0n O m0n n  n$D n O  o$H n P  p$L o @P  q P o pP `T 1o P t 7o Q  =o hQ uX Po Q v$\ Vo Q  `do no `o 8R y ` o 8R z d o R {$h o R |$l o R  }po S ~ p p S 0t p S  x #p S  | 6p T    Ep PT   Zp T  ` ip T  |p @U `p U   p U   p V ` p pV   p V  `p (W   p XW @ q   q W  `+q W  @ 9q W @  Jq X @ [q HX @ kq pX @  |q X @ q X @ q X  @ q Y $ q XY   q Y @ q Y @ q Z  @ r HZ   r xZ $@ r  'r Z $ :r Z $ Kr [ d X[ x[ $ gr [ $ {r [ @ r (\  r \  r \  ( r ]  r X] $ r 8  ] ] "$ r s  @s (^ $ ,s h^   ^ !( 3s ^ `Hs ^  [s (_ `os p_ `_ _ !( s s  h@` `` $ s ` $ s ` $ s a $ s (a $ t `a $ t a $ 4t a  $$ At a $( ]t 0b $, ot Xb $0 t b $4 t b $8 t c dt pc dt c `< t d $@ u 8  +u Pd $D =u d $H Nu d $L `u e @P tu Pe $T u 8  u e $X e f !$\ Hf pf $` u f $d u f $h u g  `p u Pg  x u g  w| v h  0 v Ph    "v h  $ 0v i $ Gv Hi  @ Sv pi $ dv i 0 wv i  7 v j  $ v hj d (v j $ v (k   v Xk $ v v  $ w k  $ $w k    2w k $ Ew p   Pw l  $ _w Xl  $ lw l  @ zw l  @ w m   w Xm  dw m $ w   w n `w pn `w n $  x n $ #x o $ >x xo $ Wx o  d "fx p  tx @p   |x xp  $ x x $ x 8  x p $ x p    x Pq  x p  y q $ $y q i `   8y q  ` $My Hr   ]y r    ky r  0@vy aFF@y s @@ y ^ (y `s  @ y  @y s  @y t    z (t @ z p  )z pt  $ 8z t   pG t    Mz (u  $ cz Xu  `( 'pz u  , z v $0 z 0@z Hv 0@z v   4 z @w $8 z pw $< z w  $@ z w $D { (x  $H { Px $L { 8  <{ xx !$P Q{ x "$T b{ 8 # t{ x  $$X { y  %$\ { @y &$` { `y  '$d { y ($h { y  )$l y z *$p { Hz +$t { pz ,$x { - | z  .$| &| z /$ :| X@ "0 M| { 1$ b| @{ 2$ x| h{  3$ | { d | { 5$ | P|  6$ | |  7$ | |  8$ | |  9$ | 8  : | } ;$ } P}  <$ } x} =$ %} }  >$ 1} }  ?$ <} 8 @ M} 8 A d} ~ B$ }} } C$ } @~  D$ } E } x~ F$} 8 `} ~  H$ ~ ~ I$ ~   J@ /~ P K  @~  L$ S~   M$ b~ 8 N ~~  O$ ~ ( P0 ~ p Q0 ~ ~ R$ ~ S$ ~ Ѐ T   U  ' 8  W(4 p  V(B  X(O Y  c r  Z$  [$  @  \$  h ]$ ^$    `_  p d (  a   hb( ( c ! p d  8  ` %F  f$ L T p  g X T p h h 8 ` )y h  j $  k ( ȅ l , m$0 8  n@ 8 o 4 ` 0@р Ȇ qp8  r X H@  t$H ؇ u$L T p v  8 w  x P 1 0  yT )2 h= C zHP z|(X a z}(\ v 8 ( z~(} 8 ( z( 8 ( z( 8 ( z( H z (`  zh ȉ hd  z h 0 zhŁ h z (l ԁ z(p  z(t P zH x #2 z@  (l  z (l   z(x P z (| . zh6 h? z( U ( z ( C ` z( d z(  z"( ~ zh  zh H h z( zh  7  p6 8 6 0D p  @ D  p6 6 0YG H  ` D p А 7 pD  7 pD P 7 p  0 0Ԃ ؂ F  @ & + (E J ( ( (d P (m r Z(    ǃ  P   ( `   P Ű (@ Г (, :  P X   g 0 Pz `  P  P    P ل P ˯  (ܯ x ( @ 0  X  0  0dz h  (  (M p  (  ( 2 p  (@ (B h  (h  (a p  (  (' x  (IJ  ( 8 (@ $  Q ( (: 0  P I ` ` Ȟ   m (  `  ( s (0 0 P  RP  (o 8 0Å p  ؅  i (  H   ( - (@ 0    x  * : Т P |   (D X P W ;< y  ְ У (d m 8 (x S    p  P 2 0 ؤ    0 P ۆ h    P % 0 @X x < ئ K Q  U H P m    ҇  (  ( 0 P p P    (  0 , H  0@ (  % 0B  Q X   0l      ʈ  ؈ 0 (@   ت    8  h ̮  ( ( !b Ы "0G  #( @ $(E p { U &%Y Ь Pp 8 P  p  (( )( Э  *X  +0T @ ,( -( x .@ P(ʼn 00Չ (   P  P4 3C 4(@ 5(  60 @ 7( 8( ذ 98 -  :  ;( X <(E =<2 б >(O  (  x @(@  A( Z в B(@V ] Ct  E ` E( F г P@  PHX x PPƊ PX!ߊ  K\ P`#  M x N($  Pd&3 ص PI   PhV ^ Pp{   @ T0  Px‹ x V  W(Ջ  X { 8  Y0 (@ x [( \(ñ  ]( !  ^(@ڱ ط _(? 8 8 B  J Q @h  w   P w   C ( 6   x Z9 l9 Q0 w9 P  Ì 9 c9 nj 9 H9 9  : : 9: Ό ]: Hp: :   :  iG  @   0 0" :  %  H: 2 K  : : H: Z j  y X @      э   :  p к     H  % p  0  ;  F  Q   \ к  g h p y  ؼ    (  P  x  @  @Ŏ ؽ  @Ҏ   @ݎ H @ p @     (   h  #  0  =   J 8  W  d  o  z   @   h   h       Ώ  (  8  h  * < h  @: H ; K HR b ,;  :; 0L;  0r u p|  p(NC (  @ 0 yE   sK $K JK K K Ɛ ʐ ϐ H 26= 2DK `2 F R 2Y`2gn 2 . P 25 < 2C J 2Q X `2_   2u| 2֐ `2 2 2 `2@ 2 2 `2' 2 2   2  h @2 $  2+ 2 > 29 @  @2G N X 2U \  2c j P 2q x  2   2   20F @ `2  p 2  p 2   @2  2 '  2i  `2   2i X 2@F  2   @2i  i /U ` ` 2     Α ܑ  N    i `   O   * 3 A i M ` /U X \ g u |    { U  ` <\l       ` u^  9  Œ h ͒   l  > rk  i  u^    - i : ` < G H M L `= : ` \ g u Q o V ^ f Z k s ;< y xE ;< { i    ^  E\ yH  ` E> ` `  "K  œ ̓ [ 3W ` <  ғ Q K   & 0 = E P FC FC   4 K U c j r |   /B /B /B /B /B   {( {( k- k- - -Ku,7D |,,<F+,v -</B , ,d D H5 ,,0u,P 7D |,,<F+,0 v ?  -<G/B P ,G  , Hd KD  H5  G, H,D F F F FFFK F!F F"F FFFF FGG  G 0G DGLGJJLJLK 2 JtE LJF n JJgJJ K< kB JJJJJJJJJJJJJJJ"5  F}L M :KK 2 J<߆JJG ^JJKJJJJK)K KKK%K0K JG WJZJ]`~ LB> J>q ;q < { H $ [02 pPD2@t2 2 appu b s F i 1 o 1ʼn dӉ X2ʊJ͊JЊJ JhJi ӊ܊ӊ_ ߊ DB < gJtK   N J oK Jd<tE Jn FJ!:$:':*: J$n ߆I L9 E-J JR0  JSo J<J?J'K 2  J+K 2 0 By,Ja 2 @ JH= KJNJK F QJFLK TJ8 KK # LK > JG WJZJ]`~ LB> J>q ;q < { H $   N          && *<<3 3 JJAA\\SSbb gx <oo::      E ~H p&H p5H  >H zEkn R8~86s@Eˢ,3ԌL "G}V y#k]h''DlqOfasIpC,\:'dye8o qH?ؘ FA*fxג"G{jfn9R, -mcouGKkp TbT X,cʦe)lZGdbB2 Ft7o MYR. *r)qo7UԼT*]d&x eJW7=w~ kʰR0[q\-tϑҀ w.΢7Jٰw& &wܵ!|8QHKG\aKڻ QC 3BnZ0O@"yFbSbw2vʱTg4i7<[ކZɦ@F2d~ ?hŝuíSjoRyGENq]ĕAɌaR@ ;aQ `ȟYrx+vh2L33@FQtG3߲J%8dTRy4oIqtz!.Lub(t<њmH-˹U`{zJ+]NfmpC_&KDٸϭ7|8DCBX_]HS G{G؊ĮʕmjZcP1MK9Ĺns2v 35%6Ώo-1pM jy9QYH̿B6Oh4ާ' 6q(Uxs6#ʅ6AU8z{ _D<+]G6 zX_tmkm9[򥏁LbdȨqSzR`GN.󻻋y p+!%A|_$!HCBc,6^߰C9t =c7.bE*+I=9Z L ȇ+3ɏ3EG5\m02FC3zKlԿ(Xw&Q^3p6ʈPUw(ǹ4w#i2@L/;#mT(8 6f m;i鼌ѶnvSL2 ^jڪ-gJq1ű$eҌs7h!wÈeЁJ<9W5N߾ m~TN'g<'W8p XN<|/7=gSq 1TDg?Sj uAcm%Zͮ:x^ QBEK4.̍dﴣPc㎡Xr=ёB9c s+MFlCQa7m;pKc^o|>*5W&(y8Z,$Ր[MPlnpIW ł!=Bx&V{ yvjj14H 3$M`G*([ y<6 4* =7|QB ,Fdڴ-1bWHn_1Ցy(ޏ0bquw2XRpB?~=SHFD{qo9ZG|!2 ,qLh!NŜ'ۨޱsBd;:b {.frg-Σխ üYE*ՠ![@.Հ|GC҆@K Q$'h}i9m`ৌȟ.yR\?;R{C4"G3= OgV7~p}m%\R餩4(*v!55WE*of|, #kCa&i贬B' VhHI*`^d 4rvɺ Y$WTu#3qk1+vd'MņV'7+^@#9P !S`݀aV/N% %]`!|ѰkMutA| MeO!aKOQv]3;w5*⢹'Ljk'+ @8 P9r5ed^z/|YyG8j(->\8q%>EuGz8uYr3\SU268'Tg*Ċ,o[pFlPA;@5VrOB&V?3?P3lXF*X+7M4Uҁpy )epLs)6G @as״O16Wh{NQ$)^ _itLڗrJ.Fh76 IЃ TwU>O*kwBWOGN(B`oL05Tsm$YZFP%g.cA*S[ D ͻe]zKq/؆?m N\Qo3(X&`GءVf^+)Y"KB,gPg> _@5eJR4 o”27Qh,hԅe^m\|; ~Yik8b*^gZ2FT(c4 1W~/cVۗv%/f{$U`WTOWS(B]٩9'~9sx@9ѐ&R: $Zwf@]ʴB.j)PRB?/P%xEYD[h-pd˯VgKc˧eJ>[w@LpE*{\)_&y-N/FPަ%ˏU U+˫oUQ&̝w8'Zݓ!oL'+JO6 ]|yAMƪL7dzIEWiJ1%o^qCʳ&`}9u#v;N,j6*%h9߅v>T"p&7]Ⱥ9vSć#hQ:0,ܽp$d ta}>^Ft{yeqL~%7&cm eyֻ` Tcn:<( RȐYׂBWRO7R֤գ9sD{rےȵwA140ΣnNNeƨ^ -柙e9;2=Yebo[i` n',+*d9. R\HCN3;|h\>'oSy{x.I\Թ kJ_%omp*\kG~E{o@Qj( r$FLoV>A)DrCXٽc 脗Ѝx0X ڙR}yPjQ4S~$zp `g@a|5l>'Y,ߢ*< 40#`qVd m hkX nN})P.rAY\l. kД1,=Rr !Wg4&N}:t JMC2Q2k̭Fq!m|k5 D?R=|ÜϝR'1Ϯ4mjPEhAӸq(a{\^/l0)L;jWF5ɷ.Z#OF|1WD|(V2\1(b&w\&sST4wۤ ɊEm)ԛoԙ1ᐊG}e$^ lMv:sE{wB-Μo&2=]02p"\aK3~[p;J:>h>.">xRz֜ږy&0N $R;y:%W59?AG|T-sl S۴O) ~%찵6_fc=r\J&t].i\, ׻ Д^u:NO:}sŤ1XMnfۛ[a >O*uP_ o{ShkVl} .,;\y,[†08Q_1Dř32JFX ;Jo}2b3Wlfy_E.Ԛ4lɹ0q%yCW z X*%FaӀ͜"1SQb!ԶR#iӮjBF9 6-^E Wlc|WBFvDЊǺʏGBqޙ٦2[<&}8RZ ׃K F*taDFZ1E/t<:}8>dk /D\RnE*ɭavn5Y#J >A |92%}0AwmSm?[XlqlV@z_ Nkzt`}XzBKXCso'uek֢i:25Lநtb:~Ƒ("1@,-\ne]ӟdzLjX":>3x޻n6k jH+Kf(?l oXtL$u罆DpCۂ<(95eViq#ڪLݑ^u@}7i;~ XĪxL1XrDu . T&Kj/*hBth%s`%p5]C3Ifd(( 7i{;TN_ytk<3 Y^dT4T7]814j ,qp,*RK8?LI V;[֦ hCqHoG5ND~"FD?"m4 Ļ).+ITdXaF5YLj:%<<~!qE0F{hvpY/A* ,cv 8hQ虈mIP2njNʽ-Hkr)T*(2W.ˑeW4؏XNfSLە}B w>/eOe\y-HJ~tUzA jIPUIpRٖhr^|/a]XȩI4!` <-rHu %/J=5+ae˨v1bě+Ȩx[dy0|}w8h-yMrQOYo+vw2z+ -eIzKt z L㰓GEoS}ܟ jx) PЅ~Nͱ:+pި\yBEIcafM]!z7NjԵ9rnFNAc |ß9%SǥﳩbuMH^*uFn>Zj*wCI4E|i9nfoz-}B1k;2TBHjEMI D'2|h|ACJ0*мUk7~jx(>mv7¾5M 6AHYPFg7w놮[w؇5M_UCCZ#"OlZ&ڔiS,zo(:8v;Oc1KڌQpSHwMi,O&G͟}~bX]BƳ@RKm(('5\ Rlcf* Rdg‘ _qkeN>e)c2/'S2벰dauEQ[װԘ%o(( 2N~3ʿ!oOu}m,-^LT%-_1!6nā/v fTmz|1& WMzXG=FZΥI۔>''g֤n"[vV0rE(MNs./m}Wpd|2N]Up} }7O@dC#Rq͆fBaV q{|,0=IBswHg8nMdm e< //_`;{wq-tU\*e IR!M9bm8~N(<1CwgaE ^_Duy.Ǎso2jQ"Yzݛ >Sɏx20 A9M- T *HLY_V =:"*ZtCE@sРʭnH\fQ^, ʖ]2DL UV{T%KB8oQ.ޞ|Ѭ8ɐN(U+/iq2z\zˮj/Y4< -LO9kƞ|{r6rKjIʓKvk'A(ʆlf>Z7L0b5Z$QHslTè~oXKv{6YNDkn C_I^0VBҿֿ_yЊ_ɀ{un5D έuI0~bw3Erk 0F\ͥy,!RV#fBڬ E&n} y6ʢLM~B.Duϒ=b$|Q 9ybU;w̛xx2R%؟)l8£HH0&yҹ)F='?l3Ǩ\ϊ&M!q (08+M$Hk.5q!,f@3AF U01n Ι-qPiF Ǎߑx@ewH'Oܧ*JHs4jcB@mxAvZ_6ɝSAA#@J p lxYSuVĜU0ޯ|:Wؐ4pC$ BǔPf!O VPjmJ&%cE@⒙=%sznSq39 Lh7Qry .OTvӀP%Z5hi&9ۥZMQ9 _MCS J-Pv4Q[r,~!"YƂs`lRlZ?ӿ> 04ߞs1Vyi$ Sԛş[DUC%$O3es43Ѽ7uji ǵSbJgZ'rrו)٣\X樥6{;jJ0ߡGH z󐀜{dHGJtcw05k `Vm!Z(SpQ4 QԿqQ:A*5&M۾{呋RR%^׈>%#6nM>; HGO7zd"쳳3>^Y ǩ|KyQ{>`2뙓TżqHCS>V;d J'MoXhIaI0m," 2ŷZP/ڡ'Կ y[4 kzF1=S-T|o" ]핍("M5r$Nug}ܳk[֋:'X~v}᢫eJ2Q.\Z%jaM"aqvbVPR+P׭lJХmu$D%QX~3mZa>.xW$MDH%'7|Ch/pGtH"$ @ؽ0w)2ǀ5Z%ov}URzπ2n1⫐QZ234eZG5TwÒR]+ύxf,#09ʨiXOuyKk9нyo^[R!9;/i SR[r-k[FL)D ݋ECok6o-[`8O,%SE/z>hBnsnQBl6*6hpZ;~kLC:) y'6[*y|T_ZNjǺ؝puT]ic{5ڷb 2^nH^K@?0/h;L?IAV0"+x?Tf+>n͹RLXTŃF^&+\[24a d'`nQР&3H&NDN8t:TX]%k!+zx; WI a{i`3id&wmӧp!<hܒi_0DIQ& Kno}( l[(5[ b(rlmkGy!߱RqCbɆ|%YWmf~;H#aWhi)gr.լ5S0:uR՝tfIJ9Fw,nTv5SVy]g\Eú[𥂋Ȉ=U=ćZfBX!ġ3Tqقѭt ;}0I_9 /IL|8I.@GGݴ.̓#%aCJpƵ7D`_\m/ZO_f\;}u9:5O&KxC:G6ʛU)z85,S0M_t Qf0zIXAnMD%e))v-X '34"7'A6u}޾-PK23zie4 Rg"Av@_%ޜCcPT}p,nHٴ&4jmr*V,1h|t.ἧnm4fDqGTcZK8T OuA0~E,wr\ҕDxvajȄl\CBN\1nɎ~5Ṫk~{̀tתasN}hIɺrAT9 |Ú@WChs(Gȓ:.픯-A< 6 @I7jtl#?p)l˜fc{hE(-0L & jn( {!<q) o3&4N7e%j_~0 CyF`(ɑub@fbJb^E=ޕLxi"D㺎c;5Za93X"f_7Yn:ScA= .b4HA7hd.Z2MF"_Cs;;B+^i6]x&`EFXyWdžPSY ڃ&A{ Fl~nx 꼰hgh5f Z:HY/g6bznxd2@R +|4Һ ~5rH]:<'`ⱙŦn1 /ܫ}oKx^֣E:D&9@?MOf[in=u;::ωژv!Rq1@`XEjzRre)~mgv% d"qȏKlW )M@[<-*6n !ql%('RJ3h8D/a MŽ0PM? V$XξZ+.ڱ#u'W]Θ^q&-$nqnIw!5tm߲1|k7ߜKi߳pT6~B53N,2 ^sPf]pB BQFVy~GlXUCUŷ:g  bn'ٮh)ʫ-Du ĔKn i;-cu\3qd ex8s tYL˰tTFQ!*>krE~hK33?fN9ǿWiF~vnK4'9:/jt3t'Z#.=jWtIDS.ߊXAVrm_m6 2&ih{8@fiKE]Gޣ|B]:TV&uQ}耞#M^V$:vTkgFk^z 6{F?}IYeqt),1cqn){'2W]Aoź %z[La{q-KOelU ȸsFҫ3ԵO-gZ߽q;*x᫣ӊ P*Q9>E<&+vԕ9>]pЃr/yϐ}V} %ECzUhJ͈"m4_fDlȅ/x9OCc?[w_괣9#'C^XHpJJ*՚&&[+Sn%PU(=/eE0ofTrw'2FdxHfUZa_Hf-#µ&dʎ+A5}XW|荑>Nwƣ.W3#@$BʯY!+6㥄HYݮ}*`*71Ga6u`р,_hS<$DJj_e'Z$rfk@'"I ROPjfsM^&78m =UF\52nXXGJ\n0Mt؄b/_bf)uU4D' fѿ>р6iaagX]0o#%I Z?uQl>A/M @l"d`6 jñuS_B 8n'GhMe Mw!γqG)=YE<8xȄTFN^ KQ^I0Ύݺ%3D!Ė4U>j  g0PGcɪI{~49?} +OIL*mlpSh]It >\ŴLg\!J'b?K,Ύ&{caneCC-\H%Xa~1S(Mc&\F&7pHAu9`$(XpT7gW(@ жP;Fᱰc#T׉UP (;BY ,V<zHPD$'摍,p™h(DTA\b]-A[kȯ73&ckhemɫׇyjZ&t+~.-X[xr h:-Ƹ[6knnIQ]eɝ[L\)4Vv?1#1 Zl0T͸?xP`QaIP&ql1$%(g Cg:*~_P/{,ծL5xO)x/F Ժ iэ] q-%a be~^.qqLBR3fwi;{y-vƬSA\8!=qr_͍O0nۺ0mK#M-ZJ^ÔYs7NI0;Hw~(%C~]> "ٸ}B2BbzNvh#6gkc yĎ/g$Phr 3, F8HG߁{ngݞ`ORm3A?2cХ%8X/楒zru~Ho>'(&Q(1kE(/^A^⥶o(7զ{)B K&(Xts~Dp5]Rb%I7T!MSRr-bn]:ܝk?jqx~IQT$)&ijȨ7R_ Qc'Ҥ{-۱G|t;MtcڥBe^?Y ~iA4iSFNJq޿⥱-4EvY]w/RMٳ tpsM[}r8V˴"Qo|猳c6QxܻK08B"o:D7eE)X2Ta ^6\N >TD̀굪u+88'AwPb4oF* ]v2.VJ>et/H&]4g Fc4z YqvdzĖk'5ïf[xSdaoN̴-/#SO Lng- >O9E-+!V`¢KtBfR'\h&0ʒ@UZ a# egb!}@]S A=L@BG 4[dSC\R_9ґi`i ۥ@%h7gTŹ6~QWF簷RNj2|NŖ D 2{nK0;NZ@9rýdskӐ{mV%%yB[Pߜ(>R./ a!\ߨшUтy'Um6֨ސ{Gm O[ZA?#Ak,0:(;dAv!$Bp#a[ P_.EA/K,CG1/} Sj01 4 친w\9|f7tuZ\ DpLl?M"CrEutP"/Cau7G ٴ1 WqOjLZ=Zej܏ACߴtI}`_W1L”("KtdXVA1rê*r>'+K&F( 6d?KHXf&o/ךMRst~b-yV<|L Z\rU$k"&⥗ ]EF3F凎=s >e o&4p!XNy$՚2]2 xL OhS]`eC7= !Mj؟ffYNSz*?/BE־4tPZeԉjT0ֵŵi )ՍyQ.<jV7Ma"؈BN(vf`<-_Ǔoe kv&N/hGʱC5+D~(mK{o]"3U: UдkE1vRpL5NON|BewʄU.<]eS9%ͳ3b." ڮF:GFG(\-Cۙ*k{,>6*"Z֔I+9 оT6 KQIrFQ@Ha{G::-&Imy<$ \97;{es`Tv2O蛿1~e}xlG'8OzK}>Z$SY︯ȔVM+jX<z!FLP_ _+wσ5u bupdBHۤw 5m&UN{deAڪw-8.۝ P+8K$֔e$9GNuEy1{\Y N<ĩb?m%xb<, +9,RӧsvA&3k0 TE_͏"\75]YGR{ڟ6['3CAO` Di ,$r)K@@e;)nZc+@ qCr\ʨzՑQr.nX uu`%؞)2]kcF!(.&^qs _ϸ\m+#܁!]锐 41/\{tOJf89ˁGFw(o< [GsXif}]Y}:ZX@vH5OiUKl;Zh{-p"T8( gnj nD-W* 3e=;[G^Yͺi.Z]q̻[Nva$e&[ ȬZgMRp2w:PC91VQ['܂O,T,R: #'D/TFD)b7 *5yL/tk)+T_'9uIL(44bۨO,5 4sh#+s3N^P00 Է*Yh`H/% ˣo惆0 m-]ĆE<4yftqq~FD>>p/fsopQZvJ[(YnvH̒W2X的j>18љyV4ߎTmtsRBzNuDa=,NO.QqTO 4VEg zONm~7n[J:,XO{3t"5|Ӏt,&ƭk Q$CFO\Q)46HϫUΕ kz?'3 ?4-PqTr<<i&#xYҒR鈜HW9Z5 {iq { |w9A盶vi8rV1#ӇHia!.0r&*enf n%f_@s A&|>.ZrD|/,|ktD.m:<Է9wԟȃ"|Ć~C'@7Jcu߈Í6ڍ3F]{x>`CO@ʝ-mN: T/C,+Z"?فtCb\EgI< GCK? bԋkv&EΏZ<$:kn0ҷ\04&?wYr Vo-Y [;29Ȭ:Ogz6YP@]K`BIdpD-m Qާ >2Sk kBbT(6(Kp7ӻ%][j/VYx&K(ADLnߤ@b66Mz7R.xdMd7&Tֳ%[LU뻐TNTZ糵guZ3v݊t(3{fj2?Aet\}cbH`{[N\ٽDId?gmE>hU]qd5K%<:92T3 .!ݕw3]@7>AFӁmeSYV*47UqFs@Q|jO[rɝ1=QLcܥջyZɉ;!6j`2薟vLZR *ndZAG 㕪Kthީ>D\&*/ wF4g$@م)K~yЃ^sOp׳߻@>x\=S."v%]kda;7Q𭱀ӡQ$} ^wwv!{k'*n@X8*\^EZJPQY>Sgn' fH[v3ܸ,]ya R@*P剔(R*G1u Y^k.O 7?/RfW6#Ps#wW$N}z6353|1]8qcee"Z9mP1(EF3CJ!wV34IS#oOŘMj[3T*zo,CH& L4#ٴ(oVG*&_1ҫS+-GW6QZ"K?3wbhܝ%6D✁(]ii^}AמӅUО Mᛋ{+g$P1B5'Ȑ&T]OE=|(x 2@ _m.CrQ={4Qw (OEEɞo ?vļ Q!NeV/XU3̉ -aOn'}s5;ŹN+)Xo0ӟ_'[Xk׬>;7olpX³߇0Gr4I4͇f:jzfo҃Zh'f9٘FüӐGɯ08&QwTlԉG)އs9d9FZlAWpXJ@k*El}~,k9`pV'Gd.*C)Eꚗ{IJ7zчFx[15-\}A"-6My ->086ڜ3%-)Ƅ B21 y_{&?-_zGc92@%35;k? N,o8d6'cU'Mn)F_?YB d7Plgce;B сQ 7 pc7ʫCj&}qb1ϑGR erwI\~7}ay,L#E5퓂ޱ p@;Pbޯf`g jA`"'o)D!k&F0ov֝ȕk`=145-x7B&9NSpy\z \rp}5҉4XRw#N֬&.Kǽw0Mƒ$H(j`4pd0KkO=Y? q68vPAſũC$zO.+[.`ZV,CY1Q:*E=VlbĖa¡ނ 8 x{> /]*|ߒ=܁3`U ? , Zh%6D Ma#7u"4VX3^SG Iɧcu0k0А_EDf"ږ &qØ9, Ydo1G%(Eƹ&&aK(y:h{{f\X:8 Eb^C,!PQyrNwp4PЕ[\gYZ.shstrtab.interp.note.gnu.property.note.ABI-tag.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rela.dyn.rela.plt.init.plt.sec.text.fini.rodata.stapsdt.base.eh_frame_hdr.eh_frame.gcc_except_table.tbss.init_array.fini_array.data.rel.ro.dynamic.got.data.bss.note.stapsdt.gnu.build.attributes.gnu_debuglink.gnu_debugdata  &   4@@$Gohh`Q pY88ao4no}B ``p? @ @ @ @ 0i 8=  `$0`$`$0`$8$0$ $0$ 828 H2H%2 +2X+ 00>s@T,c4PgIr8/iterator000064400000005124152526447510006504 0ustar00// -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file include/iterator * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_ITERATOR #define _GLIBCXX_ITERATOR 1 #pragma GCC system_header #include #include #include #include #include #include #include #include #include #endif /* _GLIBCXX_ITERATOR */ 8/streambuf000064400000072501152526447510006646 0ustar00// Stream buffer classes -*- C++ -*- // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/streambuf * This is a Standard C++ Library header. */ // // ISO C++ 14882: 27.5 Stream buffers // #ifndef _GLIBXX_STREAMBUF #define _GLIBXX_STREAMBUF 1 #pragma GCC system_header #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #define _IsUnused __attribute__ ((__unused__)) template streamsize __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>*, basic_streambuf<_CharT, _Traits>*, bool&); /** * @brief The actual work of input and output (interface). * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This is a base class. Derived stream buffers each control a * pair of character sequences: one for input, and one for output. * * Section [27.5.1] of the standard describes the requirements and * behavior of stream buffer classes. That section (three paragraphs) * is reproduced here, for simplicity and accuracy. * * -# Stream buffers can impose various constraints on the sequences * they control. Some constraints are: * - The controlled input sequence can be not readable. * - The controlled output sequence can be not writable. * - The controlled sequences can be associated with the contents of * other representations for character sequences, such as external * files. * - The controlled sequences can support operations @e directly to or * from associated sequences. * - The controlled sequences can impose limitations on how the * program can read characters from a sequence, write characters to * a sequence, put characters back into an input sequence, or alter * the stream position. * . * -# Each sequence is characterized by three pointers which, if non-null, * all point into the same @c charT array object. The array object * represents, at any moment, a (sub)sequence of characters from the * sequence. Operations performed on a sequence alter the values * stored in these pointers, perform reads and writes directly to or * from associated sequences, and alter the stream position and * conversion state as needed to maintain this subsequence relationship. * The three pointers are: * - the beginning pointer, or lowest element address in the * array (called @e xbeg here); * - the next pointer, or next element address that is a * current candidate for reading or writing (called @e xnext here); * - the end pointer, or first element address beyond the * end of the array (called @e xend here). * . * -# The following semantic constraints shall always apply for any set * of three pointers for a sequence, using the pointer names given * immediately above: * - If @e xnext is not a null pointer, then @e xbeg and @e xend shall * also be non-null pointers into the same @c charT array, as * described above; otherwise, @e xbeg and @e xend shall also be null. * - If @e xnext is not a null pointer and @e xnext < @e xend for an * output sequence, then a write position is available. * In this case, @e *xnext shall be assignable as the next element * to write (to put, or to store a character value, into the sequence). * - If @e xnext is not a null pointer and @e xbeg < @e xnext for an * input sequence, then a putback position is available. * In this case, @e xnext[-1] shall have a defined value and is the * next (preceding) element to store a character that is put back * into the input sequence. * - If @e xnext is not a null pointer and @e xnext< @e xend for an * input sequence, then a read position is available. * In this case, @e *xnext shall have a defined value and is the * next element to read (to get, or to obtain a character value, * from the sequence). */ template class basic_streambuf { public: //@{ /** * These are standard types. They permit a standardized way of * referring to names of (or names dependent on) the template * parameters, which are specific to the implementation. */ typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; //@} //@{ /// This is a non-standard type. typedef basic_streambuf __streambuf_type; //@} friend class basic_ios; friend class basic_istream; friend class basic_ostream; friend class istreambuf_iterator; friend class ostreambuf_iterator; friend streamsize __copy_streambufs_eof<>(basic_streambuf*, basic_streambuf*, bool&); template friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, _CharT2*>::__type __copy_move_a2(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, _CharT2*); template friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, istreambuf_iterator<_CharT2> >::__type find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, const _CharT2&); template friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, void>::__type advance(istreambuf_iterator<_CharT2>&, _Distance); template friend basic_istream<_CharT2, _Traits2>& operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2*); template friend basic_istream<_CharT2, _Traits2>& operator>>(basic_istream<_CharT2, _Traits2>&, basic_string<_CharT2, _Traits2, _Alloc>&); template friend basic_istream<_CharT2, _Traits2>& getline(basic_istream<_CharT2, _Traits2>&, basic_string<_CharT2, _Traits2, _Alloc>&, _CharT2); protected: /* * This is based on _IO_FILE, just reordered to be more consistent, * and is intended to be the most minimal abstraction for an * internal buffer. * - get == input == read * - put == output == write */ char_type* _M_in_beg; ///< Start of get area. char_type* _M_in_cur; ///< Current read area. char_type* _M_in_end; ///< End of get area. char_type* _M_out_beg; ///< Start of put area. char_type* _M_out_cur; ///< Current put area. char_type* _M_out_end; ///< End of put area. /// Current locale setting. locale _M_buf_locale; public: /// Destructor deallocates no buffer space. virtual ~basic_streambuf() { } // [27.5.2.2.1] locales /** * @brief Entry point for imbue(). * @param __loc The new locale. * @return The previous locale. * * Calls the derived imbue(__loc). */ locale pubimbue(const locale& __loc) { locale __tmp(this->getloc()); this->imbue(__loc); _M_buf_locale = __loc; return __tmp; } /** * @brief Locale access. * @return The current locale in effect. * * If pubimbue(loc) has been called, then the most recent @c loc * is returned. Otherwise the global locale in effect at the time * of construction is returned. */ locale getloc() const { return _M_buf_locale; } // [27.5.2.2.2] buffer management and positioning //@{ /** * @brief Entry points for derived buffer functions. * * The public versions of @c pubfoo dispatch to the protected * derived @c foo member functions, passing the arguments (if any) * and returning the result unchanged. */ basic_streambuf* pubsetbuf(char_type* __s, streamsize __n) { return this->setbuf(__s, __n); } /** * @brief Alters the stream position. * @param __off Offset. * @param __way Value for ios_base::seekdir. * @param __mode Value for ios_base::openmode. * * Calls virtual seekoff function. */ pos_type pubseekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode = ios_base::in | ios_base::out) { return this->seekoff(__off, __way, __mode); } /** * @brief Alters the stream position. * @param __sp Position * @param __mode Value for ios_base::openmode. * * Calls virtual seekpos function. */ pos_type pubseekpos(pos_type __sp, ios_base::openmode __mode = ios_base::in | ios_base::out) { return this->seekpos(__sp, __mode); } /** * @brief Calls virtual sync function. */ int pubsync() { return this->sync(); } //@} // [27.5.2.2.3] get area /** * @brief Looking ahead into the stream. * @return The number of characters available. * * If a read position is available, returns the number of characters * available for reading before the buffer must be refilled. * Otherwise returns the derived @c showmanyc(). */ streamsize in_avail() { const streamsize __ret = this->egptr() - this->gptr(); return __ret ? __ret : this->showmanyc(); } /** * @brief Getting the next character. * @return The next character, or eof. * * Calls @c sbumpc(), and if that function returns * @c traits::eof(), so does this function. Otherwise, @c sgetc(). */ int_type snextc() { int_type __ret = traits_type::eof(); if (__builtin_expect(!traits_type::eq_int_type(this->sbumpc(), __ret), true)) __ret = this->sgetc(); return __ret; } /** * @brief Getting the next character. * @return The next character, or eof. * * If the input read position is available, returns that character * and increments the read pointer, otherwise calls and returns * @c uflow(). */ int_type sbumpc() { int_type __ret; if (__builtin_expect(this->gptr() < this->egptr(), true)) { __ret = traits_type::to_int_type(*this->gptr()); this->gbump(1); } else __ret = this->uflow(); return __ret; } /** * @brief Getting the next character. * @return The next character, or eof. * * If the input read position is available, returns that character, * otherwise calls and returns @c underflow(). Does not move the * read position after fetching the character. */ int_type sgetc() { int_type __ret; if (__builtin_expect(this->gptr() < this->egptr(), true)) __ret = traits_type::to_int_type(*this->gptr()); else __ret = this->underflow(); return __ret; } /** * @brief Entry point for xsgetn. * @param __s A buffer area. * @param __n A count. * * Returns xsgetn(__s,__n). The effect is to fill @a __s[0] through * @a __s[__n-1] with characters from the input sequence, if possible. */ streamsize sgetn(char_type* __s, streamsize __n) { return this->xsgetn(__s, __n); } // [27.5.2.2.4] putback /** * @brief Pushing characters back into the input stream. * @param __c The character to push back. * @return The previous character, if possible. * * Similar to sungetc(), but @a __c is pushed onto the stream * instead of the previous character. If successful, * the next character fetched from the input stream will be @a * __c. */ int_type sputbackc(char_type __c) { int_type __ret; const bool __testpos = this->eback() < this->gptr(); if (__builtin_expect(!__testpos || !traits_type::eq(__c, this->gptr()[-1]), false)) __ret = this->pbackfail(traits_type::to_int_type(__c)); else { this->gbump(-1); __ret = traits_type::to_int_type(*this->gptr()); } return __ret; } /** * @brief Moving backwards in the input stream. * @return The previous character, if possible. * * If a putback position is available, this function decrements * the input pointer and returns that character. Otherwise, * calls and returns pbackfail(). The effect is to @a unget * the last character @a gotten. */ int_type sungetc() { int_type __ret; if (__builtin_expect(this->eback() < this->gptr(), true)) { this->gbump(-1); __ret = traits_type::to_int_type(*this->gptr()); } else __ret = this->pbackfail(); return __ret; } // [27.5.2.2.5] put area /** * @brief Entry point for all single-character output functions. * @param __c A character to output. * @return @a __c, if possible. * * One of two public output functions. * * If a write position is available for the output sequence (i.e., * the buffer is not full), stores @a __c in that position, increments * the position, and returns @c traits::to_int_type(__c). If a write * position is not available, returns @c overflow(__c). */ int_type sputc(char_type __c) { int_type __ret; if (__builtin_expect(this->pptr() < this->epptr(), true)) { *this->pptr() = __c; this->pbump(1); __ret = traits_type::to_int_type(__c); } else __ret = this->overflow(traits_type::to_int_type(__c)); return __ret; } /** * @brief Entry point for all single-character output functions. * @param __s A buffer read area. * @param __n A count. * * One of two public output functions. * * * Returns xsputn(__s,__n). The effect is to write @a __s[0] through * @a __s[__n-1] to the output sequence, if possible. */ streamsize sputn(const char_type* __s, streamsize __n) { return this->xsputn(__s, __n); } protected: /** * @brief Base constructor. * * Only called from derived constructors, and sets up all the * buffer data to zero, including the pointers described in the * basic_streambuf class description. Note that, as a result, * - the class starts with no read nor write positions available, * - this is not an error */ basic_streambuf() : _M_in_beg(0), _M_in_cur(0), _M_in_end(0), _M_out_beg(0), _M_out_cur(0), _M_out_end(0), _M_buf_locale(locale()) { } // [27.5.2.3.1] get area access //@{ /** * @brief Access to the get area. * * These functions are only available to other protected functions, * including derived classes. * * - eback() returns the beginning pointer for the input sequence * - gptr() returns the next pointer for the input sequence * - egptr() returns the end pointer for the input sequence */ char_type* eback() const { return _M_in_beg; } char_type* gptr() const { return _M_in_cur; } char_type* egptr() const { return _M_in_end; } //@} /** * @brief Moving the read position. * @param __n The delta by which to move. * * This just advances the read position without returning any data. */ void gbump(int __n) { _M_in_cur += __n; } /** * @brief Setting the three read area pointers. * @param __gbeg A pointer. * @param __gnext A pointer. * @param __gend A pointer. * @post @a __gbeg == @c eback(), @a __gnext == @c gptr(), and * @a __gend == @c egptr() */ void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) { _M_in_beg = __gbeg; _M_in_cur = __gnext; _M_in_end = __gend; } // [27.5.2.3.2] put area access //@{ /** * @brief Access to the put area. * * These functions are only available to other protected functions, * including derived classes. * * - pbase() returns the beginning pointer for the output sequence * - pptr() returns the next pointer for the output sequence * - epptr() returns the end pointer for the output sequence */ char_type* pbase() const { return _M_out_beg; } char_type* pptr() const { return _M_out_cur; } char_type* epptr() const { return _M_out_end; } //@} /** * @brief Moving the write position. * @param __n The delta by which to move. * * This just advances the write position without returning any data. */ void pbump(int __n) { _M_out_cur += __n; } /** * @brief Setting the three write area pointers. * @param __pbeg A pointer. * @param __pend A pointer. * @post @a __pbeg == @c pbase(), @a __pbeg == @c pptr(), and * @a __pend == @c epptr() */ void setp(char_type* __pbeg, char_type* __pend) { _M_out_beg = _M_out_cur = __pbeg; _M_out_end = __pend; } // [27.5.2.4] virtual functions // [27.5.2.4.1] locales /** * @brief Changes translations. * @param __loc A new locale. * * Translations done during I/O which depend on the current * locale are changed by this call. The standard adds, * Between invocations of this function a class derived * from streambuf can safely cache results of calls to locale * functions and to members of facets so obtained. * * @note Base class version does nothing. */ virtual void imbue(const locale& __loc _IsUnused) { } // [27.5.2.4.2] buffer management and positioning /** * @brief Manipulates the buffer. * * Each derived class provides its own appropriate behavior. See * the next-to-last paragraph of * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering * for more on this function. * * @note Base class version does nothing, returns @c this. */ virtual basic_streambuf* setbuf(char_type*, streamsize) { return this; } /** * @brief Alters the stream positions. * * Each derived class provides its own appropriate behavior. * @note Base class version does nothing, returns a @c pos_type * that represents an invalid stream position. */ virtual pos_type seekoff(off_type, ios_base::seekdir, ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out) { return pos_type(off_type(-1)); } /** * @brief Alters the stream positions. * * Each derived class provides its own appropriate behavior. * @note Base class version does nothing, returns a @c pos_type * that represents an invalid stream position. */ virtual pos_type seekpos(pos_type, ios_base::openmode /*__mode*/ = ios_base::in | ios_base::out) { return pos_type(off_type(-1)); } /** * @brief Synchronizes the buffer arrays with the controlled sequences. * @return -1 on failure. * * Each derived class provides its own appropriate behavior, * including the definition of @a failure. * @note Base class version does nothing, returns zero. */ virtual int sync() { return 0; } // [27.5.2.4.3] get area /** * @brief Investigating the data available. * @return An estimate of the number of characters available in the * input sequence, or -1. * * If it returns a positive value, then successive calls to * @c underflow() will not return @c traits::eof() until at * least that number of characters have been supplied. If @c * showmanyc() returns -1, then calls to @c underflow() or @c * uflow() will fail. [27.5.2.4.3]/1 * * @note Base class version does nothing, returns zero. * @note The standard adds that the intention is not only that the * calls [to underflow or uflow] will not return @c eof() but * that they will return immediately. * @note The standard adds that the morphemes of @c showmanyc are * @b es-how-many-see, not @b show-manic. */ virtual streamsize showmanyc() { return 0; } /** * @brief Multiple character extraction. * @param __s A buffer area. * @param __n Maximum number of characters to assign. * @return The number of characters assigned. * * Fills @a __s[0] through @a __s[__n-1] with characters from the input * sequence, as if by @c sbumpc(). Stops when either @a __n characters * have been copied, or when @c traits::eof() would be copied. * * It is expected that derived classes provide a more efficient * implementation by overriding this definition. */ virtual streamsize xsgetn(char_type* __s, streamsize __n); /** * @brief Fetches more data from the controlled sequence. * @return The first character from the pending sequence. * * Informally, this function is called when the input buffer is * exhausted (or does not exist, as buffering need not actually be * done). If a buffer exists, it is @a refilled. In either case, the * next available character is returned, or @c traits::eof() to * indicate a null pending sequence. * * For a formal definition of the pending sequence, see a good text * such as Langer & Kreft, or [27.5.2.4.3]/7-14. * * A functioning input streambuf can be created by overriding only * this function (no buffer area will be used). For an example, see * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html * * @note Base class version does nothing, returns eof(). */ virtual int_type underflow() { return traits_type::eof(); } /** * @brief Fetches more data from the controlled sequence. * @return The first character from the pending sequence. * * Informally, this function does the same thing as @c underflow(), * and in fact is required to call that function. It also returns * the new character, like @c underflow() does. However, this * function also moves the read position forward by one. */ virtual int_type uflow() { int_type __ret = traits_type::eof(); const bool __testeof = traits_type::eq_int_type(this->underflow(), __ret); if (!__testeof) { __ret = traits_type::to_int_type(*this->gptr()); this->gbump(1); } return __ret; } // [27.5.2.4.4] putback /** * @brief Tries to back up the input sequence. * @param __c The character to be inserted back into the sequence. * @return eof() on failure, some other value on success * @post The constraints of @c gptr(), @c eback(), and @c pptr() * are the same as for @c underflow(). * * @note Base class version does nothing, returns eof(). */ virtual int_type pbackfail(int_type __c _IsUnused = traits_type::eof()) { return traits_type::eof(); } // Put area: /** * @brief Multiple character insertion. * @param __s A buffer area. * @param __n Maximum number of characters to write. * @return The number of characters written. * * Writes @a __s[0] through @a __s[__n-1] to the output sequence, as if * by @c sputc(). Stops when either @a n characters have been * copied, or when @c sputc() would return @c traits::eof(). * * It is expected that derived classes provide a more efficient * implementation by overriding this definition. */ virtual streamsize xsputn(const char_type* __s, streamsize __n); /** * @brief Consumes data from the buffer; writes to the * controlled sequence. * @param __c An additional character to consume. * @return eof() to indicate failure, something else (usually * @a __c, or not_eof()) * * Informally, this function is called when the output buffer * is full (or does not exist, as buffering need not actually * be done). If a buffer exists, it is @a consumed, with * some effect on the controlled sequence. * (Typically, the buffer is written out to the sequence * verbatim.) In either case, the character @a c is also * written out, if @a __c is not @c eof(). * * For a formal definition of this function, see a good text * such as Langer & Kreft, or [27.5.2.4.5]/3-7. * * A functioning output streambuf can be created by overriding only * this function (no buffer area will be used). * * @note Base class version does nothing, returns eof(). */ virtual int_type overflow(int_type __c _IsUnused = traits_type::eof()) { return traits_type::eof(); } #if _GLIBCXX_USE_DEPRECATED && __cplusplus <= 201402L // Annex D.6 (removed in C++17) public: /** * @brief Tosses a character. * * Advances the read pointer, ignoring the character that would have * been read. * * See http://gcc.gnu.org/ml/libstdc++/2002-05/msg00168.html */ #if __cplusplus >= 201103L [[__deprecated__("stossc is deprecated, use sbumpc instead")]] #endif void stossc() { if (this->gptr() < this->egptr()) this->gbump(1); else this->uflow(); } #endif // Also used by specializations for char and wchar_t in src. void __safe_gbump(streamsize __n) { _M_in_cur += __n; } void __safe_pbump(streamsize __n) { _M_out_cur += __n; } #if __cplusplus < 201103L private: #else protected: #endif basic_streambuf(const basic_streambuf&); basic_streambuf& operator=(const basic_streambuf&); #if __cplusplus >= 201103L void swap(basic_streambuf& __sb) { std::swap(_M_in_beg, __sb._M_in_beg); std::swap(_M_in_cur, __sb._M_in_cur); std::swap(_M_in_end, __sb._M_in_end); std::swap(_M_out_beg, __sb._M_out_beg); std::swap(_M_out_cur, __sb._M_out_cur); std::swap(_M_out_end, __sb._M_out_end); std::swap(_M_buf_locale, __sb._M_buf_locale); } #endif }; #if __cplusplus >= 201103L template std::basic_streambuf<_CharT, _Traits>:: basic_streambuf(const basic_streambuf&) = default; template std::basic_streambuf<_CharT, _Traits>& std::basic_streambuf<_CharT, _Traits>:: operator=(const basic_streambuf&) = default; #endif // Explicit specialization declarations, defined in src/streambuf.cc. template<> streamsize __copy_streambufs_eof(basic_streambuf* __sbin, basic_streambuf* __sbout, bool& __ineof); #ifdef _GLIBCXX_USE_WCHAR_T template<> streamsize __copy_streambufs_eof(basic_streambuf* __sbin, basic_streambuf* __sbout, bool& __ineof); #endif #undef _IsUnused _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include #endif /* _GLIBCXX_STREAMBUF */ 8/ctgmath000064400000002520152526447510006277 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/ctgmath * This is a Standard C++ Library header. */ #pragma GCC system_header #ifndef _GLIBCXX_CTGMATH #define _GLIBCXX_CTGMATH 1 #if __cplusplus < 201103L # include #else # include extern "C++" { # include } #endif #endif 8/future000064400000142766152526447510006203 0ustar00// -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/future * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_FUTURE #define _GLIBCXX_FUTURE 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup futures Futures * @ingroup concurrency * * Classes for futures support. * @{ */ /// Error code for futures enum class future_errc { future_already_retrieved = 1, promise_already_satisfied, no_state, broken_promise }; /// Specialization. template<> struct is_error_code_enum : public true_type { }; /// Points to a statically-allocated object derived from error_category. const error_category& future_category() noexcept; /// Overload for make_error_code. inline error_code make_error_code(future_errc __errc) noexcept { return error_code(static_cast(__errc), future_category()); } /// Overload for make_error_condition. inline error_condition make_error_condition(future_errc __errc) noexcept { return error_condition(static_cast(__errc), future_category()); } /** * @brief Exception type thrown by futures. * @ingroup exceptions */ class future_error : public logic_error { public: explicit future_error(future_errc __errc) : future_error(std::make_error_code(__errc)) { } virtual ~future_error() noexcept; virtual const char* what() const noexcept; const error_code& code() const noexcept { return _M_code; } private: explicit future_error(error_code __ec) : logic_error("std::future_error: " + __ec.message()), _M_code(__ec) { } friend void __throw_future_error(int); error_code _M_code; }; // Forward declarations. template class future; template class shared_future; template class packaged_task; template class promise; /// Launch code for futures enum class launch { async = 1, deferred = 2 }; constexpr launch operator&(launch __x, launch __y) { return static_cast( static_cast(__x) & static_cast(__y)); } constexpr launch operator|(launch __x, launch __y) { return static_cast( static_cast(__x) | static_cast(__y)); } constexpr launch operator^(launch __x, launch __y) { return static_cast( static_cast(__x) ^ static_cast(__y)); } constexpr launch operator~(launch __x) { return static_cast(~static_cast(__x)); } inline launch& operator&=(launch& __x, launch __y) { return __x = __x & __y; } inline launch& operator|=(launch& __x, launch __y) { return __x = __x | __y; } inline launch& operator^=(launch& __x, launch __y) { return __x = __x ^ __y; } /// Status code for futures enum class future_status { ready, timeout, deferred }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2021. Further incorrect usages of result_of template using __async_result_of = typename result_of< typename decay<_Fn>::type(typename decay<_Args>::type...)>::type; template future<__async_result_of<_Fn, _Args...>> async(launch __policy, _Fn&& __fn, _Args&&... __args); template future<__async_result_of<_Fn, _Args...>> async(_Fn&& __fn, _Args&&... __args); #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) /// Base class and enclosing scope. struct __future_base { /// Base class for results. struct _Result_base { exception_ptr _M_error; _Result_base(const _Result_base&) = delete; _Result_base& operator=(const _Result_base&) = delete; // _M_destroy() allows derived classes to control deallocation virtual void _M_destroy() = 0; struct _Deleter { void operator()(_Result_base* __fr) const { __fr->_M_destroy(); } }; protected: _Result_base(); virtual ~_Result_base(); }; /// A unique_ptr for result objects. template using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>; /// A result object that has storage for an object of type _Res. template struct _Result : _Result_base { private: __gnu_cxx::__aligned_buffer<_Res> _M_storage; bool _M_initialized; public: typedef _Res result_type; _Result() noexcept : _M_initialized() { } ~_Result() { if (_M_initialized) _M_value().~_Res(); } // Return lvalue, future will add const or rvalue-reference _Res& _M_value() noexcept { return *_M_storage._M_ptr(); } void _M_set(const _Res& __res) { ::new (_M_storage._M_addr()) _Res(__res); _M_initialized = true; } void _M_set(_Res&& __res) { ::new (_M_storage._M_addr()) _Res(std::move(__res)); _M_initialized = true; } private: void _M_destroy() { delete this; } }; /// A result object that uses an allocator. template struct _Result_alloc final : _Result<_Res>, _Alloc { using __allocator_type = __alloc_rebind<_Alloc, _Result_alloc>; explicit _Result_alloc(const _Alloc& __a) : _Result<_Res>(), _Alloc(__a) { } private: void _M_destroy() { __allocator_type __a(*this); __allocated_ptr<__allocator_type> __guard_ptr{ __a, this }; this->~_Result_alloc(); } }; // Create a result object that uses an allocator. template static _Ptr<_Result_alloc<_Res, _Allocator>> _S_allocate_result(const _Allocator& __a) { using __result_type = _Result_alloc<_Res, _Allocator>; typename __result_type::__allocator_type __a2(__a); auto __guard = std::__allocate_guarded(__a2); __result_type* __p = ::new((void*)__guard.get()) __result_type{__a}; __guard = nullptr; return _Ptr<__result_type>(__p); } // Keep it simple for std::allocator. template static _Ptr<_Result<_Res>> _S_allocate_result(const std::allocator<_Tp>& __a) { return _Ptr<_Result<_Res>>(new _Result<_Res>); } // Base class for various types of shared state created by an // asynchronous provider (such as a std::promise) and shared with one // or more associated futures. class _State_baseV2 { typedef _Ptr<_Result_base> _Ptr_type; enum _Status : unsigned { __not_ready, __ready }; _Ptr_type _M_result; __atomic_futex_unsigned<> _M_status; atomic_flag _M_retrieved = ATOMIC_FLAG_INIT; once_flag _M_once; public: _State_baseV2() noexcept : _M_result(), _M_status(_Status::__not_ready) { } _State_baseV2(const _State_baseV2&) = delete; _State_baseV2& operator=(const _State_baseV2&) = delete; virtual ~_State_baseV2() = default; _Result_base& wait() { // Run any deferred function or join any asynchronous thread: _M_complete_async(); // Acquire MO makes sure this synchronizes with the thread that made // the future ready. _M_status._M_load_when_equal(_Status::__ready, memory_order_acquire); return *_M_result; } template future_status wait_for(const chrono::duration<_Rep, _Period>& __rel) { // First, check if the future has been made ready. Use acquire MO // to synchronize with the thread that made it ready. if (_M_status._M_load(memory_order_acquire) == _Status::__ready) return future_status::ready; if (_M_is_deferred_future()) return future_status::deferred; if (_M_status._M_load_when_equal_for(_Status::__ready, memory_order_acquire, __rel)) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2100. timed waiting functions must also join // This call is a no-op by default except on an async future, // in which case the async thread is joined. It's also not a // no-op for a deferred future, but such a future will never // reach this point because it returns future_status::deferred // instead of waiting for the future to become ready (see // above). Async futures synchronize in this call, so we need // no further synchronization here. _M_complete_async(); return future_status::ready; } return future_status::timeout; } template future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs) { // First, check if the future has been made ready. Use acquire MO // to synchronize with the thread that made it ready. if (_M_status._M_load(memory_order_acquire) == _Status::__ready) return future_status::ready; if (_M_is_deferred_future()) return future_status::deferred; if (_M_status._M_load_when_equal_until(_Status::__ready, memory_order_acquire, __abs)) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2100. timed waiting functions must also join // See wait_for(...) above. _M_complete_async(); return future_status::ready; } return future_status::timeout; } // Provide a result to the shared state and make it ready. // Calls at most once: _M_result = __res(); void _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false) { bool __did_set = false; // all calls to this function are serialized, // side-effects of invoking __res only happen once call_once(_M_once, &_State_baseV2::_M_do_set, this, std::__addressof(__res), std::__addressof(__did_set)); if (__did_set) // Use release MO to synchronize with observers of the ready state. _M_status._M_store_notify_all(_Status::__ready, memory_order_release); else if (!__ignore_failure) __throw_future_error(int(future_errc::promise_already_satisfied)); } // Provide a result to the shared state but delay making it ready // until the calling thread exits. // Calls at most once: _M_result = __res(); void _M_set_delayed_result(function<_Ptr_type()> __res, weak_ptr<_State_baseV2> __self) { bool __did_set = false; unique_ptr<_Make_ready> __mr{new _Make_ready}; // all calls to this function are serialized, // side-effects of invoking __res only happen once call_once(_M_once, &_State_baseV2::_M_do_set, this, std::__addressof(__res), std::__addressof(__did_set)); if (!__did_set) __throw_future_error(int(future_errc::promise_already_satisfied)); __mr->_M_shared_state = std::move(__self); __mr->_M_set(); __mr.release(); } // Abandon this shared state. void _M_break_promise(_Ptr_type __res) { if (static_cast(__res)) { __res->_M_error = make_exception_ptr(future_error(future_errc::broken_promise)); // This function is only called when the last asynchronous result // provider is abandoning this shared state, so noone can be // trying to make the shared state ready at the same time, and // we can access _M_result directly instead of through call_once. _M_result.swap(__res); // Use release MO to synchronize with observers of the ready state. _M_status._M_store_notify_all(_Status::__ready, memory_order_release); } } // Called when this object is first passed to a future. void _M_set_retrieved_flag() { if (_M_retrieved.test_and_set()) __throw_future_error(int(future_errc::future_already_retrieved)); } template struct _Setter; // set lvalues template struct _Setter<_Res, _Arg&> { // check this is only used by promise::set_value(const R&) // or promise::set_value(R&) static_assert(is_same<_Res, _Arg&>::value // promise || is_same::value, // promise "Invalid specialisation"); // Used by std::promise to copy construct the result. typename promise<_Res>::_Ptr_type operator()() const { _M_promise->_M_storage->_M_set(*_M_arg); return std::move(_M_promise->_M_storage); } promise<_Res>* _M_promise; _Arg* _M_arg; }; // set rvalues template struct _Setter<_Res, _Res&&> { // Used by std::promise to move construct the result. typename promise<_Res>::_Ptr_type operator()() const { _M_promise->_M_storage->_M_set(std::move(*_M_arg)); return std::move(_M_promise->_M_storage); } promise<_Res>* _M_promise; _Res* _M_arg; }; // set void template struct _Setter<_Res, void> { static_assert(is_void<_Res>::value, "Only used for promise"); typename promise<_Res>::_Ptr_type operator()() const { return std::move(_M_promise->_M_storage); } promise<_Res>* _M_promise; }; struct __exception_ptr_tag { }; // set exceptions template struct _Setter<_Res, __exception_ptr_tag> { // Used by std::promise to store an exception as the result. typename promise<_Res>::_Ptr_type operator()() const { _M_promise->_M_storage->_M_error = *_M_ex; return std::move(_M_promise->_M_storage); } promise<_Res>* _M_promise; exception_ptr* _M_ex; }; template static _Setter<_Res, _Arg&&> __setter(promise<_Res>* __prom, _Arg&& __arg) { _S_check(__prom->_M_future); return _Setter<_Res, _Arg&&>{ __prom, std::__addressof(__arg) }; } template static _Setter<_Res, __exception_ptr_tag> __setter(exception_ptr& __ex, promise<_Res>* __prom) { _S_check(__prom->_M_future); return _Setter<_Res, __exception_ptr_tag>{ __prom, &__ex }; } template static _Setter<_Res, void> __setter(promise<_Res>* __prom) { _S_check(__prom->_M_future); return _Setter<_Res, void>{ __prom }; } template static void _S_check(const shared_ptr<_Tp>& __p) { if (!static_cast(__p)) __throw_future_error((int)future_errc::no_state); } private: // The function invoked with std::call_once(_M_once, ...). void _M_do_set(function<_Ptr_type()>* __f, bool* __did_set) { _Ptr_type __res = (*__f)(); // Notify the caller that we did try to set; if we do not throw an // exception, the caller will be aware that it did set (e.g., see // _M_set_result). *__did_set = true; _M_result.swap(__res); // nothrow } // Wait for completion of async function. virtual void _M_complete_async() { } // Return true if state corresponds to a deferred function. virtual bool _M_is_deferred_future() const { return false; } struct _Make_ready final : __at_thread_exit_elt { weak_ptr<_State_baseV2> _M_shared_state; static void _S_run(void*); void _M_set(); }; }; #ifdef _GLIBCXX_ASYNC_ABI_COMPAT class _State_base; class _Async_state_common; #else using _State_base = _State_baseV2; class _Async_state_commonV2; #endif template()())> class _Deferred_state; template()())> class _Async_state_impl; template class _Task_state_base; template class _Task_state; template static std::shared_ptr<_State_base> _S_make_deferred_state(_BoundFn&& __fn); template static std::shared_ptr<_State_base> _S_make_async_state(_BoundFn&& __fn); template struct _Task_setter; template static _Task_setter<_Res_ptr, _BoundFn> _S_task_setter(_Res_ptr& __ptr, _BoundFn& __call) { return { std::__addressof(__ptr), std::__addressof(__call) }; } }; /// Partial specialization for reference types. template struct __future_base::_Result<_Res&> : __future_base::_Result_base { typedef _Res& result_type; _Result() noexcept : _M_value_ptr() { } void _M_set(_Res& __res) noexcept { _M_value_ptr = std::addressof(__res); } _Res& _M_get() noexcept { return *_M_value_ptr; } private: _Res* _M_value_ptr; void _M_destroy() { delete this; } }; /// Explicit specialization for void. template<> struct __future_base::_Result : __future_base::_Result_base { typedef void result_type; private: void _M_destroy() { delete this; } }; #ifndef _GLIBCXX_ASYNC_ABI_COMPAT // Allow _Setter objects to be stored locally in std::function template struct __is_location_invariant <__future_base::_State_base::_Setter<_Res, _Arg>> : true_type { }; // Allow _Task_setter objects to be stored locally in std::function template struct __is_location_invariant <__future_base::_Task_setter<_Res_ptr, _Fn, _Res>> : true_type { }; /// Common implementation for future and shared_future. template class __basic_future : public __future_base { protected: typedef shared_ptr<_State_base> __state_type; typedef __future_base::_Result<_Res>& __result_type; private: __state_type _M_state; public: // Disable copying. __basic_future(const __basic_future&) = delete; __basic_future& operator=(const __basic_future&) = delete; bool valid() const noexcept { return static_cast(_M_state); } void wait() const { _State_base::_S_check(_M_state); _M_state->wait(); } template future_status wait_for(const chrono::duration<_Rep, _Period>& __rel) const { _State_base::_S_check(_M_state); return _M_state->wait_for(__rel); } template future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const { _State_base::_S_check(_M_state); return _M_state->wait_until(__abs); } protected: /// Wait for the state to be ready and rethrow any stored exception __result_type _M_get_result() const { _State_base::_S_check(_M_state); _Result_base& __res = _M_state->wait(); if (!(__res._M_error == 0)) rethrow_exception(__res._M_error); return static_cast<__result_type>(__res); } void _M_swap(__basic_future& __that) noexcept { _M_state.swap(__that._M_state); } // Construction of a future by promise::get_future() explicit __basic_future(const __state_type& __state) : _M_state(__state) { _State_base::_S_check(_M_state); _M_state->_M_set_retrieved_flag(); } // Copy construction from a shared_future explicit __basic_future(const shared_future<_Res>&) noexcept; // Move construction from a shared_future explicit __basic_future(shared_future<_Res>&&) noexcept; // Move construction from a future explicit __basic_future(future<_Res>&&) noexcept; constexpr __basic_future() noexcept : _M_state() { } struct _Reset { explicit _Reset(__basic_future& __fut) noexcept : _M_fut(__fut) { } ~_Reset() { _M_fut._M_state.reset(); } __basic_future& _M_fut; }; }; /// Primary template for future. template class future : public __basic_future<_Res> { friend class promise<_Res>; template friend class packaged_task; template friend future<__async_result_of<_Fn, _Args...>> async(launch, _Fn&&, _Args&&...); typedef __basic_future<_Res> _Base_type; typedef typename _Base_type::__state_type __state_type; explicit future(const __state_type& __state) : _Base_type(__state) { } public: constexpr future() noexcept : _Base_type() { } /// Move constructor future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } // Disable copying future(const future&) = delete; future& operator=(const future&) = delete; future& operator=(future&& __fut) noexcept { future(std::move(__fut))._M_swap(*this); return *this; } /// Retrieving the value _Res get() { typename _Base_type::_Reset __reset(*this); return std::move(this->_M_get_result()._M_value()); } shared_future<_Res> share() noexcept; }; /// Partial specialization for future template class future<_Res&> : public __basic_future<_Res&> { friend class promise<_Res&>; template friend class packaged_task; template friend future<__async_result_of<_Fn, _Args...>> async(launch, _Fn&&, _Args&&...); typedef __basic_future<_Res&> _Base_type; typedef typename _Base_type::__state_type __state_type; explicit future(const __state_type& __state) : _Base_type(__state) { } public: constexpr future() noexcept : _Base_type() { } /// Move constructor future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } // Disable copying future(const future&) = delete; future& operator=(const future&) = delete; future& operator=(future&& __fut) noexcept { future(std::move(__fut))._M_swap(*this); return *this; } /// Retrieving the value _Res& get() { typename _Base_type::_Reset __reset(*this); return this->_M_get_result()._M_get(); } shared_future<_Res&> share() noexcept; }; /// Explicit specialization for future template<> class future : public __basic_future { friend class promise; template friend class packaged_task; template friend future<__async_result_of<_Fn, _Args...>> async(launch, _Fn&&, _Args&&...); typedef __basic_future _Base_type; typedef typename _Base_type::__state_type __state_type; explicit future(const __state_type& __state) : _Base_type(__state) { } public: constexpr future() noexcept : _Base_type() { } /// Move constructor future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } // Disable copying future(const future&) = delete; future& operator=(const future&) = delete; future& operator=(future&& __fut) noexcept { future(std::move(__fut))._M_swap(*this); return *this; } /// Retrieving the value void get() { typename _Base_type::_Reset __reset(*this); this->_M_get_result(); } shared_future share() noexcept; }; /// Primary template for shared_future. template class shared_future : public __basic_future<_Res> { typedef __basic_future<_Res> _Base_type; public: constexpr shared_future() noexcept : _Base_type() { } /// Copy constructor shared_future(const shared_future& __sf) noexcept : _Base_type(__sf) { } /// Construct from a future rvalue shared_future(future<_Res>&& __uf) noexcept : _Base_type(std::move(__uf)) { } /// Construct from a shared_future rvalue shared_future(shared_future&& __sf) noexcept : _Base_type(std::move(__sf)) { } shared_future& operator=(const shared_future& __sf) noexcept { shared_future(__sf)._M_swap(*this); return *this; } shared_future& operator=(shared_future&& __sf) noexcept { shared_future(std::move(__sf))._M_swap(*this); return *this; } /// Retrieving the value const _Res& get() const { return this->_M_get_result()._M_value(); } }; /// Partial specialization for shared_future template class shared_future<_Res&> : public __basic_future<_Res&> { typedef __basic_future<_Res&> _Base_type; public: constexpr shared_future() noexcept : _Base_type() { } /// Copy constructor shared_future(const shared_future& __sf) : _Base_type(__sf) { } /// Construct from a future rvalue shared_future(future<_Res&>&& __uf) noexcept : _Base_type(std::move(__uf)) { } /// Construct from a shared_future rvalue shared_future(shared_future&& __sf) noexcept : _Base_type(std::move(__sf)) { } shared_future& operator=(const shared_future& __sf) { shared_future(__sf)._M_swap(*this); return *this; } shared_future& operator=(shared_future&& __sf) noexcept { shared_future(std::move(__sf))._M_swap(*this); return *this; } /// Retrieving the value _Res& get() const { return this->_M_get_result()._M_get(); } }; /// Explicit specialization for shared_future template<> class shared_future : public __basic_future { typedef __basic_future _Base_type; public: constexpr shared_future() noexcept : _Base_type() { } /// Copy constructor shared_future(const shared_future& __sf) : _Base_type(__sf) { } /// Construct from a future rvalue shared_future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { } /// Construct from a shared_future rvalue shared_future(shared_future&& __sf) noexcept : _Base_type(std::move(__sf)) { } shared_future& operator=(const shared_future& __sf) { shared_future(__sf)._M_swap(*this); return *this; } shared_future& operator=(shared_future&& __sf) noexcept { shared_future(std::move(__sf))._M_swap(*this); return *this; } // Retrieving the value void get() const { this->_M_get_result(); } }; // Now we can define the protected __basic_future constructors. template inline __basic_future<_Res>:: __basic_future(const shared_future<_Res>& __sf) noexcept : _M_state(__sf._M_state) { } template inline __basic_future<_Res>:: __basic_future(shared_future<_Res>&& __sf) noexcept : _M_state(std::move(__sf._M_state)) { } template inline __basic_future<_Res>:: __basic_future(future<_Res>&& __uf) noexcept : _M_state(std::move(__uf._M_state)) { } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2556. Wide contract for future::share() template inline shared_future<_Res> future<_Res>::share() noexcept { return shared_future<_Res>(std::move(*this)); } template inline shared_future<_Res&> future<_Res&>::share() noexcept { return shared_future<_Res&>(std::move(*this)); } inline shared_future future::share() noexcept { return shared_future(std::move(*this)); } /// Primary template for promise template class promise { typedef __future_base::_State_base _State; typedef __future_base::_Result<_Res> _Res_type; typedef __future_base::_Ptr<_Res_type> _Ptr_type; template friend class _State::_Setter; friend _State; shared_ptr<_State> _M_future; _Ptr_type _M_storage; public: promise() : _M_future(std::make_shared<_State>()), _M_storage(new _Res_type()) { } promise(promise&& __rhs) noexcept : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } template promise(allocator_arg_t, const _Allocator& __a) : _M_future(std::allocate_shared<_State>(__a)), _M_storage(__future_base::_S_allocate_result<_Res>(__a)) { } template promise(allocator_arg_t, const _Allocator&, promise&& __rhs) : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } promise(const promise&) = delete; ~promise() { if (static_cast(_M_future) && !_M_future.unique()) _M_future->_M_break_promise(std::move(_M_storage)); } // Assignment promise& operator=(promise&& __rhs) noexcept { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise&) = delete; void swap(promise& __rhs) noexcept { _M_future.swap(__rhs._M_future); _M_storage.swap(__rhs._M_storage); } // Retrieving the result future<_Res> get_future() { return future<_Res>(_M_future); } // Setting the result void set_value(const _Res& __r) { _M_future->_M_set_result(_State::__setter(this, __r)); } void set_value(_Res&& __r) { _M_future->_M_set_result(_State::__setter(this, std::move(__r))); } void set_exception(exception_ptr __p) { _M_future->_M_set_result(_State::__setter(__p, this)); } void set_value_at_thread_exit(const _Res& __r) { _M_future->_M_set_delayed_result(_State::__setter(this, __r), _M_future); } void set_value_at_thread_exit(_Res&& __r) { _M_future->_M_set_delayed_result( _State::__setter(this, std::move(__r)), _M_future); } void set_exception_at_thread_exit(exception_ptr __p) { _M_future->_M_set_delayed_result(_State::__setter(__p, this), _M_future); } }; template inline void swap(promise<_Res>& __x, promise<_Res>& __y) noexcept { __x.swap(__y); } template struct uses_allocator, _Alloc> : public true_type { }; /// Partial specialization for promise template class promise<_Res&> { typedef __future_base::_State_base _State; typedef __future_base::_Result<_Res&> _Res_type; typedef __future_base::_Ptr<_Res_type> _Ptr_type; template friend class _State::_Setter; friend _State; shared_ptr<_State> _M_future; _Ptr_type _M_storage; public: promise() : _M_future(std::make_shared<_State>()), _M_storage(new _Res_type()) { } promise(promise&& __rhs) noexcept : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } template promise(allocator_arg_t, const _Allocator& __a) : _M_future(std::allocate_shared<_State>(__a)), _M_storage(__future_base::_S_allocate_result<_Res&>(__a)) { } template promise(allocator_arg_t, const _Allocator&, promise&& __rhs) : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } promise(const promise&) = delete; ~promise() { if (static_cast(_M_future) && !_M_future.unique()) _M_future->_M_break_promise(std::move(_M_storage)); } // Assignment promise& operator=(promise&& __rhs) noexcept { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise&) = delete; void swap(promise& __rhs) noexcept { _M_future.swap(__rhs._M_future); _M_storage.swap(__rhs._M_storage); } // Retrieving the result future<_Res&> get_future() { return future<_Res&>(_M_future); } // Setting the result void set_value(_Res& __r) { _M_future->_M_set_result(_State::__setter(this, __r)); } void set_exception(exception_ptr __p) { _M_future->_M_set_result(_State::__setter(__p, this)); } void set_value_at_thread_exit(_Res& __r) { _M_future->_M_set_delayed_result(_State::__setter(this, __r), _M_future); } void set_exception_at_thread_exit(exception_ptr __p) { _M_future->_M_set_delayed_result(_State::__setter(__p, this), _M_future); } }; /// Explicit specialization for promise template<> class promise { typedef __future_base::_State_base _State; typedef __future_base::_Result _Res_type; typedef __future_base::_Ptr<_Res_type> _Ptr_type; template friend class _State::_Setter; friend _State; shared_ptr<_State> _M_future; _Ptr_type _M_storage; public: promise() : _M_future(std::make_shared<_State>()), _M_storage(new _Res_type()) { } promise(promise&& __rhs) noexcept : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } template promise(allocator_arg_t, const _Allocator& __a) : _M_future(std::allocate_shared<_State>(__a)), _M_storage(__future_base::_S_allocate_result(__a)) { } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2095. missing constructors needed for uses-allocator construction template promise(allocator_arg_t, const _Allocator&, promise&& __rhs) : _M_future(std::move(__rhs._M_future)), _M_storage(std::move(__rhs._M_storage)) { } promise(const promise&) = delete; ~promise() { if (static_cast(_M_future) && !_M_future.unique()) _M_future->_M_break_promise(std::move(_M_storage)); } // Assignment promise& operator=(promise&& __rhs) noexcept { promise(std::move(__rhs)).swap(*this); return *this; } promise& operator=(const promise&) = delete; void swap(promise& __rhs) noexcept { _M_future.swap(__rhs._M_future); _M_storage.swap(__rhs._M_storage); } // Retrieving the result future get_future() { return future(_M_future); } // Setting the result void set_value() { _M_future->_M_set_result(_State::__setter(this)); } void set_exception(exception_ptr __p) { _M_future->_M_set_result(_State::__setter(__p, this)); } void set_value_at_thread_exit() { _M_future->_M_set_delayed_result(_State::__setter(this), _M_future); } void set_exception_at_thread_exit(exception_ptr __p) { _M_future->_M_set_delayed_result(_State::__setter(__p, this), _M_future); } }; template struct __future_base::_Task_setter { // Invoke the function and provide the result to the caller. _Ptr_type operator()() const { __try { (*_M_result)->_M_set((*_M_fn)()); } __catch(const __cxxabiv1::__forced_unwind&) { __throw_exception_again; // will cause broken_promise } __catch(...) { (*_M_result)->_M_error = current_exception(); } return std::move(*_M_result); } _Ptr_type* _M_result; _Fn* _M_fn; }; template struct __future_base::_Task_setter<_Ptr_type, _Fn, void> { _Ptr_type operator()() const { __try { (*_M_fn)(); } __catch(const __cxxabiv1::__forced_unwind&) { __throw_exception_again; // will cause broken_promise } __catch(...) { (*_M_result)->_M_error = current_exception(); } return std::move(*_M_result); } _Ptr_type* _M_result; _Fn* _M_fn; }; // Holds storage for a packaged_task's result. template struct __future_base::_Task_state_base<_Res(_Args...)> : __future_base::_State_base { typedef _Res _Res_type; template _Task_state_base(const _Alloc& __a) : _M_result(_S_allocate_result<_Res>(__a)) { } // Invoke the stored task and make the state ready. virtual void _M_run(_Args&&... __args) = 0; // Invoke the stored task and make the state ready at thread exit. virtual void _M_run_delayed(_Args&&... __args, weak_ptr<_State_base>) = 0; virtual shared_ptr<_Task_state_base> _M_reset() = 0; typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type; _Ptr_type _M_result; }; // Holds a packaged_task's stored task. template struct __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)> final : __future_base::_Task_state_base<_Res(_Args...)> { template _Task_state(_Fn2&& __fn, const _Alloc& __a) : _Task_state_base<_Res(_Args...)>(__a), _M_impl(std::forward<_Fn2>(__fn), __a) { } private: virtual void _M_run(_Args&&... __args) { auto __boundfn = [&] () -> typename result_of<_Fn&(_Args&&...)>::type { return std::__invoke(_M_impl._M_fn, std::forward<_Args>(__args)...); }; this->_M_set_result(_S_task_setter(this->_M_result, __boundfn)); } virtual void _M_run_delayed(_Args&&... __args, weak_ptr<_State_base> __self) { auto __boundfn = [&] () -> typename result_of<_Fn&(_Args&&...)>::type { return std::__invoke(_M_impl._M_fn, std::forward<_Args>(__args)...); }; this->_M_set_delayed_result(_S_task_setter(this->_M_result, __boundfn), std::move(__self)); } virtual shared_ptr<_Task_state_base<_Res(_Args...)>> _M_reset(); struct _Impl : _Alloc { template _Impl(_Fn2&& __fn, const _Alloc& __a) : _Alloc(__a), _M_fn(std::forward<_Fn2>(__fn)) { } _Fn _M_fn; } _M_impl; }; template static shared_ptr<__future_base::_Task_state_base<_Signature>> __create_task_state(_Fn&& __fn, const _Alloc& __a) { typedef typename decay<_Fn>::type _Fn2; typedef __future_base::_Task_state<_Fn2, _Alloc, _Signature> _State; return std::allocate_shared<_State>(__a, std::forward<_Fn>(__fn), __a); } template shared_ptr<__future_base::_Task_state_base<_Res(_Args...)>> __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)>::_M_reset() { return __create_task_state<_Res(_Args...)>(std::move(_M_impl._M_fn), static_cast<_Alloc&>(_M_impl)); } template::type>::value> struct __constrain_pkgdtask { typedef void __type; }; template struct __constrain_pkgdtask<_Task, _Fn, true> { }; /// packaged_task template class packaged_task<_Res(_ArgTypes...)> { typedef __future_base::_Task_state_base<_Res(_ArgTypes...)> _State_type; shared_ptr<_State_type> _M_state; public: // Construction and destruction packaged_task() noexcept { } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2095. missing constructors needed for uses-allocator construction template packaged_task(allocator_arg_t, const _Allocator& __a) noexcept { } template::__type> explicit packaged_task(_Fn&& __fn) : packaged_task(allocator_arg, std::allocator(), std::forward<_Fn>(__fn)) { } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2097. packaged_task constructors should be constrained // 2407. [this constructor should not be] explicit template::__type> packaged_task(allocator_arg_t, const _Alloc& __a, _Fn&& __fn) : _M_state(__create_task_state<_Res(_ArgTypes...)>( std::forward<_Fn>(__fn), __a)) { } ~packaged_task() { if (static_cast(_M_state) && !_M_state.unique()) _M_state->_M_break_promise(std::move(_M_state->_M_result)); } // No copy packaged_task(const packaged_task&) = delete; packaged_task& operator=(const packaged_task&) = delete; template packaged_task(allocator_arg_t, const _Allocator&, const packaged_task&) = delete; // Move support packaged_task(packaged_task&& __other) noexcept { this->swap(__other); } template packaged_task(allocator_arg_t, const _Allocator&, packaged_task&& __other) noexcept { this->swap(__other); } packaged_task& operator=(packaged_task&& __other) noexcept { packaged_task(std::move(__other)).swap(*this); return *this; } void swap(packaged_task& __other) noexcept { _M_state.swap(__other._M_state); } bool valid() const noexcept { return static_cast(_M_state); } // Result retrieval future<_Res> get_future() { return future<_Res>(_M_state); } // Execution void operator()(_ArgTypes... __args) { __future_base::_State_base::_S_check(_M_state); _M_state->_M_run(std::forward<_ArgTypes>(__args)...); } void make_ready_at_thread_exit(_ArgTypes... __args) { __future_base::_State_base::_S_check(_M_state); _M_state->_M_run_delayed(std::forward<_ArgTypes>(__args)..., _M_state); } void reset() { __future_base::_State_base::_S_check(_M_state); packaged_task __tmp; __tmp._M_state = _M_state; _M_state = _M_state->_M_reset(); } }; /// swap template inline void swap(packaged_task<_Res(_ArgTypes...)>& __x, packaged_task<_Res(_ArgTypes...)>& __y) noexcept { __x.swap(__y); } template struct uses_allocator, _Alloc> : public true_type { }; // Shared state created by std::async(). // Holds a deferred function and storage for its result. template class __future_base::_Deferred_state final : public __future_base::_State_base { public: explicit _Deferred_state(_BoundFn&& __fn) : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)) { } private: typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type; _Ptr_type _M_result; _BoundFn _M_fn; // Run the deferred function. virtual void _M_complete_async() { // Multiple threads can call a waiting function on the future and // reach this point at the same time. The call_once in _M_set_result // ensures only the first one run the deferred function, stores the // result in _M_result, swaps that with the base _M_result and makes // the state ready. Tell _M_set_result to ignore failure so all later // calls do nothing. _M_set_result(_S_task_setter(_M_result, _M_fn), true); } // Caller should check whether the state is ready first, because this // function will return true even after the deferred function has run. virtual bool _M_is_deferred_future() const { return true; } }; // Common functionality hoisted out of the _Async_state_impl template. class __future_base::_Async_state_commonV2 : public __future_base::_State_base { protected: ~_Async_state_commonV2() = default; // Make waiting functions block until the thread completes, as if joined. // // This function is used by wait() to satisfy the first requirement below // and by wait_for() / wait_until() to satisfy the second. // // [futures.async]: // // — a call to a waiting function on an asynchronous return object that // shares the shared state created by this async call shall block until // the associated thread has completed, as if joined, or else time out. // // — the associated thread completion synchronizes with the return from // the first function that successfully detects the ready status of the // shared state or with the return from the last function that releases // the shared state, whichever happens first. virtual void _M_complete_async() { _M_join(); } void _M_join() { std::call_once(_M_once, &thread::join, &_M_thread); } thread _M_thread; once_flag _M_once; }; // Shared state created by std::async(). // Starts a new thread that runs a function and makes the shared state ready. template class __future_base::_Async_state_impl final : public __future_base::_Async_state_commonV2 { public: explicit _Async_state_impl(_BoundFn&& __fn) : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)) { _M_thread = std::thread{ [this] { __try { _M_set_result(_S_task_setter(_M_result, _M_fn)); } __catch (const __cxxabiv1::__forced_unwind&) { // make the shared state ready on thread cancellation if (static_cast(_M_result)) this->_M_break_promise(std::move(_M_result)); __throw_exception_again; } } }; } // Must not destroy _M_result and _M_fn until the thread finishes. // Call join() directly rather than through _M_join() because no other // thread can be referring to this state if it is being destroyed. ~_Async_state_impl() { if (_M_thread.joinable()) _M_thread.join(); } private: typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type; _Ptr_type _M_result; _BoundFn _M_fn; }; template inline std::shared_ptr<__future_base::_State_base> __future_base::_S_make_deferred_state(_BoundFn&& __fn) { typedef typename remove_reference<_BoundFn>::type __fn_type; typedef _Deferred_state<__fn_type> __state_type; return std::make_shared<__state_type>(std::move(__fn)); } template inline std::shared_ptr<__future_base::_State_base> __future_base::_S_make_async_state(_BoundFn&& __fn) { typedef typename remove_reference<_BoundFn>::type __fn_type; typedef _Async_state_impl<__fn_type> __state_type; return std::make_shared<__state_type>(std::move(__fn)); } /// async template future<__async_result_of<_Fn, _Args...>> async(launch __policy, _Fn&& __fn, _Args&&... __args) { std::shared_ptr<__future_base::_State_base> __state; if ((__policy & launch::async) == launch::async) { __try { __state = __future_base::_S_make_async_state( std::thread::__make_invoker(std::forward<_Fn>(__fn), std::forward<_Args>(__args)...) ); } #if __cpp_exceptions catch(const system_error& __e) { if (__e.code() != errc::resource_unavailable_try_again || (__policy & launch::deferred) != launch::deferred) throw; } #endif } if (!__state) { __state = __future_base::_S_make_deferred_state( std::thread::__make_invoker(std::forward<_Fn>(__fn), std::forward<_Args>(__args)...)); } return future<__async_result_of<_Fn, _Args...>>(__state); } /// async, potential overload template inline future<__async_result_of<_Fn, _Args...>> async(_Fn&& __fn, _Args&&... __args) { return std::async(launch::async|launch::deferred, std::forward<_Fn>(__fn), std::forward<_Args>(__args)...); } #endif // _GLIBCXX_ASYNC_ABI_COMPAT #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 // @} group futures _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #endif // _GLIBCXX_FUTURE 8/istream000064400000100113152526447510006311 0ustar00// Input streams -*- C++ -*- // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // // ISO C++ 14882: 27.6.1 Input streams // /** @file include/istream * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_ISTREAM #define _GLIBCXX_ISTREAM 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Template class basic_istream. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This is the base class for all input streams. It provides text * formatting of all builtin types, and communicates with any class * derived from basic_streambuf to do the actual input. */ template class basic_istream : virtual public basic_ios<_CharT, _Traits> { public: // Types (inherited from basic_ios (27.4.4)): typedef _CharT char_type; typedef typename _Traits::int_type int_type; typedef typename _Traits::pos_type pos_type; typedef typename _Traits::off_type off_type; typedef _Traits traits_type; // Non-standard Types: typedef basic_streambuf<_CharT, _Traits> __streambuf_type; typedef basic_ios<_CharT, _Traits> __ios_type; typedef basic_istream<_CharT, _Traits> __istream_type; typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > __num_get_type; typedef ctype<_CharT> __ctype_type; protected: // Data Members: /** * The number of characters extracted in the previous unformatted * function; see gcount(). */ streamsize _M_gcount; public: /** * @brief Base constructor. * * This ctor is almost never called by the user directly, rather from * derived classes' initialization lists, which pass a pointer to * their own stream buffer. */ explicit basic_istream(__streambuf_type* __sb) : _M_gcount(streamsize(0)) { this->init(__sb); } /** * @brief Base destructor. * * This does very little apart from providing a virtual base dtor. */ virtual ~basic_istream() { _M_gcount = streamsize(0); } /// Safe prefix/suffix operations. class sentry; friend class sentry; //@{ /** * @brief Interface for manipulators. * * Manipulators such as @c std::ws and @c std::dec use these * functions in constructs like * std::cin >> std::ws. * For more information, see the iomanip header. */ __istream_type& operator>>(__istream_type& (*__pf)(__istream_type&)) { return __pf(*this); } __istream_type& operator>>(__ios_type& (*__pf)(__ios_type&)) { __pf(*this); return *this; } __istream_type& operator>>(ios_base& (*__pf)(ios_base&)) { __pf(*this); return *this; } //@} //@{ /** * @name Extractors * * All the @c operator>> functions (aka formatted input * functions) have some common behavior. Each starts by * constructing a temporary object of type std::basic_istream::sentry * with the second argument (noskipws) set to false. This has several * effects, concluding with the setting of a status flag; see the * sentry documentation for more. * * If the sentry status is good, the function tries to extract * whatever data is appropriate for the type of the argument. * * If an exception is thrown during extraction, ios_base::badbit * will be turned on in the stream's error state (without causing an * ios_base::failure to be thrown) and the original exception will * be rethrown if badbit is set in the exceptions mask. */ //@{ /** * @brief Integer arithmetic extractors * @param __n A variable of builtin integral type. * @return @c *this if successful * * These functions use the stream's current locale (specifically, the * @c num_get facet) to parse the input data. */ __istream_type& operator>>(bool& __n) { return _M_extract(__n); } __istream_type& operator>>(short& __n); __istream_type& operator>>(unsigned short& __n) { return _M_extract(__n); } __istream_type& operator>>(int& __n); __istream_type& operator>>(unsigned int& __n) { return _M_extract(__n); } __istream_type& operator>>(long& __n) { return _M_extract(__n); } __istream_type& operator>>(unsigned long& __n) { return _M_extract(__n); } #ifdef _GLIBCXX_USE_LONG_LONG __istream_type& operator>>(long long& __n) { return _M_extract(__n); } __istream_type& operator>>(unsigned long long& __n) { return _M_extract(__n); } #endif //@} //@{ /** * @brief Floating point arithmetic extractors * @param __f A variable of builtin floating point type. * @return @c *this if successful * * These functions use the stream's current locale (specifically, the * @c num_get facet) to parse the input data. */ __istream_type& operator>>(float& __f) { return _M_extract(__f); } __istream_type& operator>>(double& __f) { return _M_extract(__f); } __istream_type& operator>>(long double& __f) { return _M_extract(__f); } //@} /** * @brief Basic arithmetic extractors * @param __p A variable of pointer type. * @return @c *this if successful * * These functions use the stream's current locale (specifically, the * @c num_get facet) to parse the input data. */ __istream_type& operator>>(void*& __p) { return _M_extract(__p); } /** * @brief Extracting into another streambuf. * @param __sb A pointer to a streambuf * * This function behaves like one of the basic arithmetic extractors, * in that it also constructs a sentry object and has the same error * handling behavior. * * If @p __sb is NULL, the stream will set failbit in its error state. * * Characters are extracted from this stream and inserted into the * @p __sb streambuf until one of the following occurs: * * - the input stream reaches end-of-file, * - insertion into the output buffer fails (in this case, the * character that would have been inserted is not extracted), or * - an exception occurs (and in this case is caught) * * If the function inserts no characters, failbit is set. */ __istream_type& operator>>(__streambuf_type* __sb); //@} // [27.6.1.3] unformatted input /** * @brief Character counting * @return The number of characters extracted by the previous * unformatted input function dispatched for this stream. */ streamsize gcount() const { return _M_gcount; } //@{ /** * @name Unformatted Input Functions * * All the unformatted input functions have some common behavior. * Each starts by constructing a temporary object of type * std::basic_istream::sentry with the second argument (noskipws) * set to true. This has several effects, concluding with the * setting of a status flag; see the sentry documentation for more. * * If the sentry status is good, the function tries to extract * whatever data is appropriate for the type of the argument. * * The number of characters extracted is stored for later retrieval * by gcount(). * * If an exception is thrown during extraction, ios_base::badbit * will be turned on in the stream's error state (without causing an * ios_base::failure to be thrown) and the original exception will * be rethrown if badbit is set in the exceptions mask. */ /** * @brief Simple extraction. * @return A character, or eof(). * * Tries to extract a character. If none are available, sets failbit * and returns traits::eof(). */ int_type get(); /** * @brief Simple extraction. * @param __c The character in which to store data. * @return *this * * Tries to extract a character and store it in @a __c. If none are * available, sets failbit and returns traits::eof(). * * @note This function is not overloaded on signed char and * unsigned char. */ __istream_type& get(char_type& __c); /** * @brief Simple multiple-character extraction. * @param __s Pointer to an array. * @param __n Maximum number of characters to store in @a __s. * @param __delim A "stop" character. * @return *this * * Characters are extracted and stored into @a __s until one of the * following happens: * * - @c __n-1 characters are stored * - the input sequence reaches EOF * - the next character equals @a __delim, in which case the character * is not extracted * * If no characters are stored, failbit is set in the stream's error * state. * * In any case, a null character is stored into the next location in * the array. * * @note This function is not overloaded on signed char and * unsigned char. */ __istream_type& get(char_type* __s, streamsize __n, char_type __delim); /** * @brief Simple multiple-character extraction. * @param __s Pointer to an array. * @param __n Maximum number of characters to store in @a s. * @return *this * * Returns @c get(__s,__n,widen('\\n')). */ __istream_type& get(char_type* __s, streamsize __n) { return this->get(__s, __n, this->widen('\n')); } /** * @brief Extraction into another streambuf. * @param __sb A streambuf in which to store data. * @param __delim A "stop" character. * @return *this * * Characters are extracted and inserted into @a __sb until one of the * following happens: * * - the input sequence reaches EOF * - insertion into the output buffer fails (in this case, the * character that would have been inserted is not extracted) * - the next character equals @a __delim (in this case, the character * is not extracted) * - an exception occurs (and in this case is caught) * * If no characters are stored, failbit is set in the stream's error * state. */ __istream_type& get(__streambuf_type& __sb, char_type __delim); /** * @brief Extraction into another streambuf. * @param __sb A streambuf in which to store data. * @return *this * * Returns @c get(__sb,widen('\\n')). */ __istream_type& get(__streambuf_type& __sb) { return this->get(__sb, this->widen('\n')); } /** * @brief String extraction. * @param __s A character array in which to store the data. * @param __n Maximum number of characters to extract. * @param __delim A "stop" character. * @return *this * * Extracts and stores characters into @a __s until one of the * following happens. Note that these criteria are required to be * tested in the order listed here, to allow an input line to exactly * fill the @a __s array without setting failbit. * * -# the input sequence reaches end-of-file, in which case eofbit * is set in the stream error state * -# the next character equals @c __delim, in which case the character * is extracted (and therefore counted in @c gcount()) but not stored * -# @c __n-1 characters are stored, in which case failbit is set * in the stream error state * * If no characters are extracted, failbit is set. (An empty line of * input should therefore not cause failbit to be set.) * * In any case, a null character is stored in the next location in * the array. */ __istream_type& getline(char_type* __s, streamsize __n, char_type __delim); /** * @brief String extraction. * @param __s A character array in which to store the data. * @param __n Maximum number of characters to extract. * @return *this * * Returns @c getline(__s,__n,widen('\\n')). */ __istream_type& getline(char_type* __s, streamsize __n) { return this->getline(__s, __n, this->widen('\n')); } /** * @brief Discarding characters * @param __n Number of characters to discard. * @param __delim A "stop" character. * @return *this * * Extracts characters and throws them away until one of the * following happens: * - if @a __n @c != @c std::numeric_limits::max(), @a __n * characters are extracted * - the input sequence reaches end-of-file * - the next character equals @a __delim (in this case, the character * is extracted); note that this condition will never occur if * @a __delim equals @c traits::eof(). * * NB: Provide three overloads, instead of the single function * (with defaults) mandated by the Standard: this leads to a * better performing implementation, while still conforming to * the Standard. */ __istream_type& ignore(streamsize __n, int_type __delim); __istream_type& ignore(streamsize __n); __istream_type& ignore(); /** * @brief Looking ahead in the stream * @return The next character, or eof(). * * If, after constructing the sentry object, @c good() is false, * returns @c traits::eof(). Otherwise reads but does not extract * the next input character. */ int_type peek(); /** * @brief Extraction without delimiters. * @param __s A character array. * @param __n Maximum number of characters to store. * @return *this * * If the stream state is @c good(), extracts characters and stores * them into @a __s until one of the following happens: * - @a __n characters are stored * - the input sequence reaches end-of-file, in which case the error * state is set to @c failbit|eofbit. * * @note This function is not overloaded on signed char and * unsigned char. */ __istream_type& read(char_type* __s, streamsize __n); /** * @brief Extraction until the buffer is exhausted, but no more. * @param __s A character array. * @param __n Maximum number of characters to store. * @return The number of characters extracted. * * Extracts characters and stores them into @a __s depending on the * number of characters remaining in the streambuf's buffer, * @c rdbuf()->in_avail(), called @c A here: * - if @c A @c == @c -1, sets eofbit and extracts no characters * - if @c A @c == @c 0, extracts no characters * - if @c A @c > @c 0, extracts @c min(A,n) * * The goal is to empty the current buffer, and to not request any * more from the external input sequence controlled by the streambuf. */ streamsize readsome(char_type* __s, streamsize __n); /** * @brief Unextracting a single character. * @param __c The character to push back into the input stream. * @return *this * * If @c rdbuf() is not null, calls @c rdbuf()->sputbackc(c). * * If @c rdbuf() is null or if @c sputbackc() fails, sets badbit in * the error state. * * @note This function first clears eofbit. Since no characters * are extracted, the next call to @c gcount() will return 0, * as required by DR 60. */ __istream_type& putback(char_type __c); /** * @brief Unextracting the previous character. * @return *this * * If @c rdbuf() is not null, calls @c rdbuf()->sungetc(c). * * If @c rdbuf() is null or if @c sungetc() fails, sets badbit in * the error state. * * @note This function first clears eofbit. Since no characters * are extracted, the next call to @c gcount() will return 0, * as required by DR 60. */ __istream_type& unget(); /** * @brief Synchronizing the stream buffer. * @return 0 on success, -1 on failure * * If @c rdbuf() is a null pointer, returns -1. * * Otherwise, calls @c rdbuf()->pubsync(), and if that returns -1, * sets badbit and returns -1. * * Otherwise, returns 0. * * @note This function does not count the number of characters * extracted, if any, and therefore does not affect the next * call to @c gcount(). */ int sync(); /** * @brief Getting the current read position. * @return A file position object. * * If @c fail() is not false, returns @c pos_type(-1) to indicate * failure. Otherwise returns @c rdbuf()->pubseekoff(0,cur,in). * * @note This function does not count the number of characters * extracted, if any, and therefore does not affect the next * call to @c gcount(). At variance with putback, unget and * seekg, eofbit is not cleared first. */ pos_type tellg(); /** * @brief Changing the current read position. * @param __pos A file position object. * @return *this * * If @c fail() is not true, calls @c rdbuf()->pubseekpos(__pos). If * that function fails, sets failbit. * * @note This function first clears eofbit. It does not count the * number of characters extracted, if any, and therefore does * not affect the next call to @c gcount(). */ __istream_type& seekg(pos_type); /** * @brief Changing the current read position. * @param __off A file offset object. * @param __dir The direction in which to seek. * @return *this * * If @c fail() is not true, calls @c rdbuf()->pubseekoff(__off,__dir). * If that function fails, sets failbit. * * @note This function first clears eofbit. It does not count the * number of characters extracted, if any, and therefore does * not affect the next call to @c gcount(). */ __istream_type& seekg(off_type, ios_base::seekdir); //@} protected: basic_istream() : _M_gcount(streamsize(0)) { this->init(0); } #if __cplusplus >= 201103L basic_istream(const basic_istream&) = delete; basic_istream(basic_istream&& __rhs) : __ios_type(), _M_gcount(__rhs._M_gcount) { __ios_type::move(__rhs); __rhs._M_gcount = 0; } // 27.7.3.3 Assign/swap basic_istream& operator=(const basic_istream&) = delete; basic_istream& operator=(basic_istream&& __rhs) { swap(__rhs); return *this; } void swap(basic_istream& __rhs) { __ios_type::swap(__rhs); std::swap(_M_gcount, __rhs._M_gcount); } #endif template __istream_type& _M_extract(_ValueT& __v); }; /// Explicit specialization declarations, defined in src/istream.cc. template<> basic_istream& basic_istream:: getline(char_type* __s, streamsize __n, char_type __delim); template<> basic_istream& basic_istream:: ignore(streamsize __n); template<> basic_istream& basic_istream:: ignore(streamsize __n, int_type __delim); #ifdef _GLIBCXX_USE_WCHAR_T template<> basic_istream& basic_istream:: getline(char_type* __s, streamsize __n, char_type __delim); template<> basic_istream& basic_istream:: ignore(streamsize __n); template<> basic_istream& basic_istream:: ignore(streamsize __n, int_type __delim); #endif /** * @brief Performs setup work for input streams. * * Objects of this class are created before all of the standard * extractors are run. It is responsible for exception-safe * prefix and suffix operations, although only prefix actions * are currently required by the standard. */ template class basic_istream<_CharT, _Traits>::sentry { // Data Members. bool _M_ok; public: /// Easy access to dependent types. typedef _Traits traits_type; typedef basic_streambuf<_CharT, _Traits> __streambuf_type; typedef basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::__ctype_type __ctype_type; typedef typename _Traits::int_type __int_type; /** * @brief The constructor performs all the work. * @param __is The input stream to guard. * @param __noskipws Whether to consume whitespace or not. * * If the stream state is good (@a __is.good() is true), then the * following actions are performed, otherwise the sentry state * is false (not okay) and failbit is set in the * stream state. * * The sentry's preparatory actions are: * * -# if the stream is tied to an output stream, @c is.tie()->flush() * is called to synchronize the output sequence * -# if @a __noskipws is false, and @c ios_base::skipws is set in * @c is.flags(), the sentry extracts and discards whitespace * characters from the stream. The currently imbued locale is * used to determine whether each character is whitespace. * * If the stream state is still good, then the sentry state becomes * true (@a okay). */ explicit sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws = false); /** * @brief Quick status checking. * @return The sentry state. * * For ease of use, sentries may be converted to booleans. The * return value is that of the sentry state (true == okay). */ #if __cplusplus >= 201103L explicit #endif operator bool() const { return _M_ok; } }; //@{ /** * @brief Character extractors * @param __in An input stream. * @param __c A character reference. * @return in * * Behaves like one of the formatted arithmetic extractors described in * std::basic_istream. After constructing a sentry object with good * status, this function extracts a character (if one is available) and * stores it in @a __c. Otherwise, sets failbit in the input stream. */ template basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c); template inline basic_istream& operator>>(basic_istream& __in, unsigned char& __c) { return (__in >> reinterpret_cast(__c)); } template inline basic_istream& operator>>(basic_istream& __in, signed char& __c) { return (__in >> reinterpret_cast(__c)); } //@} //@{ /** * @brief Character string extractors * @param __in An input stream. * @param __s A pointer to a character array. * @return __in * * Behaves like one of the formatted arithmetic extractors described in * std::basic_istream. After constructing a sentry object with good * status, this function extracts up to @c n characters and stores them * into the array starting at @a __s. @c n is defined as: * * - if @c width() is greater than zero, @c n is width() otherwise * - @c n is the number of elements of the largest array of * * - @c char_type that can store a terminating @c eos. * - [27.6.1.2.3]/6 * * Characters are extracted and stored until one of the following happens: * - @c n-1 characters are stored * - EOF is reached * - the next character is whitespace according to the current locale * - the next character is a null byte (i.e., @c charT() ) * * @c width(0) is then called for the input stream. * * If no characters are extracted, sets failbit. */ template basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s); // Explicit specialization declaration, defined in src/istream.cc. template<> basic_istream& operator>>(basic_istream& __in, char* __s); template inline basic_istream& operator>>(basic_istream& __in, unsigned char* __s) { return (__in >> reinterpret_cast(__s)); } template inline basic_istream& operator>>(basic_istream& __in, signed char* __s) { return (__in >> reinterpret_cast(__s)); } //@} /** * @brief Template class basic_iostream * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class multiply inherits from the input and output stream classes * simply to provide a single interface. */ template class basic_iostream : public basic_istream<_CharT, _Traits>, public basic_ostream<_CharT, _Traits> { public: // _GLIBCXX_RESOLVE_LIB_DEFECTS // 271. basic_iostream missing typedefs // Types (inherited): typedef _CharT char_type; typedef typename _Traits::int_type int_type; typedef typename _Traits::pos_type pos_type; typedef typename _Traits::off_type off_type; typedef _Traits traits_type; // Non-standard Types: typedef basic_istream<_CharT, _Traits> __istream_type; typedef basic_ostream<_CharT, _Traits> __ostream_type; /** * @brief Constructor does nothing. * * Both of the parent classes are initialized with the same * streambuf pointer passed to this constructor. */ explicit basic_iostream(basic_streambuf<_CharT, _Traits>* __sb) : __istream_type(__sb), __ostream_type(__sb) { } /** * @brief Destructor does nothing. */ virtual ~basic_iostream() { } protected: basic_iostream() : __istream_type(), __ostream_type() { } #if __cplusplus >= 201103L basic_iostream(const basic_iostream&) = delete; basic_iostream(basic_iostream&& __rhs) : __istream_type(std::move(__rhs)), __ostream_type(*this) { } // 27.7.3.3 Assign/swap basic_iostream& operator=(const basic_iostream&) = delete; basic_iostream& operator=(basic_iostream&& __rhs) { swap(__rhs); return *this; } void swap(basic_iostream& __rhs) { __istream_type::swap(__rhs); } #endif }; /** * @brief Quick and easy way to eat whitespace * * This manipulator extracts whitespace characters, stopping when the * next character is non-whitespace, or when the input sequence is empty. * If the sequence is empty, @c eofbit is set in the stream, but not * @c failbit. * * The current locale is used to distinguish whitespace characters. * * Example: * @code * MyClass mc; * * std::cin >> std::ws >> mc; * @endcode * will skip leading whitespace before calling operator>> on cin and your * object. Note that the same effect can be achieved by creating a * std::basic_istream::sentry inside your definition of operator>>. */ template basic_istream<_CharT, _Traits>& ws(basic_istream<_CharT, _Traits>& __is); #if __cplusplus >= 201103L template basic_istream<_Ch, _Up>& __is_convertible_to_basic_istream_test(basic_istream<_Ch, _Up>*); template struct __is_convertible_to_basic_istream_impl { using __istream_type = void; }; template using __do_is_convertible_to_basic_istream_impl = decltype(__is_convertible_to_basic_istream_test (declval::type*>())); template struct __is_convertible_to_basic_istream_impl <_Tp, __void_t<__do_is_convertible_to_basic_istream_impl<_Tp>>> { using __istream_type = __do_is_convertible_to_basic_istream_impl<_Tp>; }; template struct __is_convertible_to_basic_istream : __is_convertible_to_basic_istream_impl<_Tp> { public: using type = __not_::__istream_type>>; constexpr static bool value = type::value; }; template struct __is_extractable : false_type {}; template struct __is_extractable<_Istream, _Tp, __void_t() >> declval<_Tp>())>> : true_type {}; template using __rvalue_istream_type = typename __is_convertible_to_basic_istream< _Istream>::__istream_type; // [27.7.1.6] Rvalue stream extraction // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2328. Rvalue stream extraction should use perfect forwarding /** * @brief Generic extractor for rvalue stream * @param __is An input stream. * @param __x A reference to the extraction target. * @return is * * This is just a forwarding function to allow extraction from * rvalue streams since they won't bind to the extractor functions * that take an lvalue reference. */ template inline typename enable_if<__and_<__not_>, __is_convertible_to_basic_istream<_Istream>, __is_extractable< __rvalue_istream_type<_Istream>, _Tp&&>>::value, __rvalue_istream_type<_Istream>>::type operator>>(_Istream&& __is, _Tp&& __x) { __rvalue_istream_type<_Istream> __ret_is = __is; __ret_is >> std::forward<_Tp>(__x); return __ret_is; } #endif // C++11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include #endif /* _GLIBCXX_ISTREAM */ 8/string000064400000003624152526447510006164 0ustar00// Components for manipulating sequences of characters -*- C++ -*- // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/string * This is a Standard C++ Library header. */ // // ISO C++ 14882: 21 Strings library // #ifndef _GLIBCXX_STRING #define _GLIBCXX_STRING 1 #pragma GCC system_header #include #include #include // NB: In turn includes stl_algobase.h #include #include #include // For operators >>, <<, and getline. #include #include #include #include #include // For less #include #include #include #include #include #endif /* _GLIBCXX_STRING */ 8/cerrno000064400000003352152526447510006144 0ustar00// The -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file cerrno * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c errno.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 19.3 Error numbers // #pragma GCC system_header #include #include #ifndef _GLIBCXX_CERRNO #define _GLIBCXX_CERRNO 1 // Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 #ifndef errno #define errno errno #endif #endif 8/stack000064400000004527152526447510005766 0ustar00// -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file include/stack * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_STACK #define _GLIBCXX_STACK 1 #pragma GCC system_header #include #include #endif /* _GLIBCXX_STACK */ 8/new000064400000016541152526447510005451 0ustar00// The -*- C++ -*- dynamic memory management header. // Copyright (C) 1994-2018 Free Software Foundation, Inc. // This file is part of GCC. // // GCC is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3, or (at your option) // any later version. // // GCC 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 General Public License for more details. // // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file new * This is a Standard C++ Library header. * * The header @c new defines several functions to manage dynamic memory and * handling memory allocation errors; see * http://gcc.gnu.org/onlinedocs/libstdc++/18_support/howto.html#4 for more. */ #ifndef _NEW #define _NEW #pragma GCC system_header #include #include #pragma GCC visibility push(default) extern "C++" { namespace std { /** * @brief Exception possibly thrown by @c new. * @ingroup exceptions * * @c bad_alloc (or classes derived from it) is used to report allocation * errors from the throwing forms of @c new. */ class bad_alloc : public exception { public: bad_alloc() throw() { } // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_alloc() throw(); // See comment in eh_exception.cc. virtual const char* what() const throw(); }; #if __cplusplus >= 201103L class bad_array_new_length : public bad_alloc { public: bad_array_new_length() throw() { } // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_array_new_length() throw(); // See comment in eh_exception.cc. virtual const char* what() const throw(); }; #endif #if __cpp_aligned_new enum class align_val_t: size_t {}; #endif struct nothrow_t { #if __cplusplus >= 201103L explicit nothrow_t() = default; #endif }; extern const nothrow_t nothrow; /** If you write your own error handler to be called by @c new, it must * be of this type. */ typedef void (*new_handler)(); /// Takes a replacement handler as the argument, returns the /// previous handler. new_handler set_new_handler(new_handler) throw(); #if __cplusplus >= 201103L /// Return the current new handler. new_handler get_new_handler() noexcept; #endif } // namespace std //@{ /** These are replaceable signatures: * - normal single new and delete (no arguments, throw @c bad_alloc on error) * - normal array new and delete (same) * - @c nothrow single new and delete (take a @c nothrow argument, return * @c NULL on error) * - @c nothrow array new and delete (same) * * Placement new and delete signatures (take a memory address argument, * does nothing) may not be replaced by a user's program. */ void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc) __attribute__((__externally_visible__)); void* operator new[](std::size_t) _GLIBCXX_THROW (std::bad_alloc) __attribute__((__externally_visible__)); void operator delete(void*) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); #if __cpp_sized_deallocation void operator delete(void*, std::size_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*, std::size_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); #endif void* operator new(std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void* operator new[](std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete(void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); #if __cpp_aligned_new void* operator new(std::size_t, std::align_val_t) __attribute__((__externally_visible__)); void* operator new(std::size_t, std::align_val_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete(void*, std::align_val_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete(void*, std::align_val_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void* operator new[](std::size_t, std::align_val_t) __attribute__((__externally_visible__)); void* operator new[](std::size_t, std::align_val_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*, std::align_val_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*, std::align_val_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); #if __cpp_sized_deallocation void operator delete(void*, std::size_t, std::align_val_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); void operator delete[](void*, std::size_t, std::align_val_t) _GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__)); #endif // __cpp_sized_deallocation #endif // __cpp_aligned_new // Default placement versions of operator new. inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT { return __p; } inline void* operator new[](std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT { return __p; } // Default placement versions of operator delete. inline void operator delete (void*, void*) _GLIBCXX_USE_NOEXCEPT { } inline void operator delete[](void*, void*) _GLIBCXX_USE_NOEXCEPT { } //@} } // extern "C++" #if __cplusplus >= 201703L #if __GNUC__ >= 7 # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1 #elif defined __has_builtin // For non-GNU compilers: # if __has_builtin(__builtin_launder) # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1 # endif #endif #ifdef _GLIBCXX_HAVE_BUILTIN_LAUNDER namespace std { #define __cpp_lib_launder 201606 /// Pointer optimization barrier [ptr.launder] template [[nodiscard]] constexpr _Tp* launder(_Tp* __p) noexcept { return __builtin_launder(__p); } // The program is ill-formed if T is a function type or // (possibly cv-qualified) void. template void launder(_Ret (*)(_Args...) _GLIBCXX_NOEXCEPT_QUAL) = delete; template void launder(_Ret (*)(_Args......) _GLIBCXX_NOEXCEPT_QUAL) = delete; void launder(void*) = delete; void launder(const void*) = delete; void launder(volatile void*) = delete; void launder(const volatile void*) = delete; } #endif // _GLIBCXX_HAVE_BUILTIN_LAUNDER #undef _GLIBCXX_HAVE_BUILTIN_LAUNDER #endif // C++17 #pragma GCC visibility pop #endif 8/random000064400000003234152526447510006133 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/random * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_RANDOM #define _GLIBCXX_RANDOM 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #include #ifdef _GLIBCXX_USE_C99_STDINT_TR1 #include // For uint_fast32_t, uint_fast64_t, uint_least32_t #include #include #include #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif // _GLIBCXX_RANDOM 8/backward/hash_set000064400000041453152526447510010234 0ustar00// Hashing set implementation -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * Copyright (c) 1996 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ /** @file backward/hash_set * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _BACKWARD_HASH_SET #define _BACKWARD_HASH_SET 1 #ifndef _GLIBCXX_PERMIT_BACKWARD_HASH #include "backward_warning.h" #endif #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::equal_to; using std::allocator; using std::pair; using std::_Identity; /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template, class _EqualKey = equal_to<_Value>, class _Alloc = allocator<_Value> > class hash_set { // concept requirements __glibcxx_class_requires(_Value, _SGIAssignableConcept) __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) private: typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, _Alloc> _Ht; _Ht _M_ht; public: typedef typename _Ht::key_type key_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Alloc::pointer pointer; typedef typename _Alloc::const_pointer const_pointer; typedef typename _Alloc::reference reference; typedef typename _Alloc::const_reference const_reference; typedef typename _Ht::const_iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } hash_set() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_set(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_set(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} template hash_set(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_set(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_set(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_set(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_unique(__f, __l); } size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); } template friend bool operator==(const hash_set<_Val, _HF, _EqK, _Al>&, const hash_set<_Val, _HF, _EqK, _Al>&); iterator begin() const { return _M_ht.begin(); } iterator end() const { return _M_ht.end(); } pair insert(const value_type& __obj) { pair __p = _M_ht.insert_unique(__obj); return pair(__p.first, __p.second); } template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f, __l); } pair insert_noresize(const value_type& __obj) { pair __p = _M_ht.insert_unique_noresize(__obj); return pair(__p.first, __p.second); } iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } size_type erase(const key_type& __key) {return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } void clear() { _M_ht.clear(); } void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template inline bool operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) { return __hs1._M_ht == __hs2._M_ht; } template inline bool operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) { return !(__hs1 == __hs2); } template inline void swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { __hs1.swap(__hs2); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template, class _EqualKey = equal_to<_Value>, class _Alloc = allocator<_Value> > class hash_multiset { // concept requirements __glibcxx_class_requires(_Value, _SGIAssignableConcept) __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) private: typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, _Alloc> _Ht; _Ht _M_ht; public: typedef typename _Ht::key_type key_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Alloc::pointer pointer; typedef typename _Alloc::const_pointer const_pointer; typedef typename _Alloc::reference reference; typedef typename _Alloc::const_reference const_reference; typedef typename _Ht::const_iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } hash_multiset() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_multiset(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_multiset(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} template hash_multiset(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_equal(__f, __l); } size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); } template friend bool operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&, const hash_multiset<_Val, _HF, _EqK, _Al>&); iterator begin() const { return _M_ht.begin(); } iterator end() const { return _M_ht.end(); } iterator insert(const value_type& __obj) { return _M_ht.insert_equal(__obj); } template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } iterator insert_noresize(const value_type& __obj) { return _M_ht.insert_equal_noresize(__obj); } iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } size_type erase(const key_type& __key) { return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } void clear() { _M_ht.clear(); } void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template inline bool operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { return __hs1._M_ht == __hs2._M_ht; } template inline bool operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { return !(__hs1 == __hs2); } template inline void swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { __hs1.swap(__hs2); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Specialization of insert_iterator so that it will work for hash_set // and hash_multiset. template class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> > { protected: typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> _Container; _Container* container; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; template class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> > { protected: typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> _Container; _Container* container; typename _Container::iterator iter; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/backward/hashtable.h000064400000101667152526447510010623 0ustar00// Hashtable implementation used by containers -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ /** @file backward/hashtable.h * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _BACKWARD_HASHTABLE_H #define _BACKWARD_HASHTABLE_H 1 // Hashtable class, used to implement the hashed associative containers // hash_set, hash_map, hash_multiset, and hash_multimap. #include #include #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; using std::forward_iterator_tag; using std::input_iterator_tag; using std::_Construct; using std::_Destroy; using std::distance; using std::vector; using std::pair; using std::__iterator_category; template struct _Hashtable_node { _Hashtable_node* _M_next; _Val _M_val; }; template > class hashtable; template struct _Hashtable_iterator; template struct _Hashtable_const_iterator; template struct _Hashtable_iterator { typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> _Hashtable; typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> iterator; typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> const_iterator; typedef _Hashtable_node<_Val> _Node; typedef forward_iterator_tag iterator_category; typedef _Val value_type; typedef ptrdiff_t difference_type; typedef size_t size_type; typedef _Val& reference; typedef _Val* pointer; _Node* _M_cur; _Hashtable* _M_ht; _Hashtable_iterator(_Node* __n, _Hashtable* __tab) : _M_cur(__n), _M_ht(__tab) { } _Hashtable_iterator() { } reference operator*() const { return _M_cur->_M_val; } pointer operator->() const { return &(operator*()); } iterator& operator++(); iterator operator++(int); bool operator==(const iterator& __it) const { return _M_cur == __it._M_cur; } bool operator!=(const iterator& __it) const { return _M_cur != __it._M_cur; } }; template struct _Hashtable_const_iterator { typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> _Hashtable; typedef _Hashtable_iterator<_Val,_Key,_HashFcn, _ExtractKey,_EqualKey,_Alloc> iterator; typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> const_iterator; typedef _Hashtable_node<_Val> _Node; typedef forward_iterator_tag iterator_category; typedef _Val value_type; typedef ptrdiff_t difference_type; typedef size_t size_type; typedef const _Val& reference; typedef const _Val* pointer; const _Node* _M_cur; const _Hashtable* _M_ht; _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) : _M_cur(__n), _M_ht(__tab) { } _Hashtable_const_iterator() { } _Hashtable_const_iterator(const iterator& __it) : _M_cur(__it._M_cur), _M_ht(__it._M_ht) { } reference operator*() const { return _M_cur->_M_val; } pointer operator->() const { return &(operator*()); } const_iterator& operator++(); const_iterator operator++(int); bool operator==(const const_iterator& __it) const { return _M_cur == __it._M_cur; } bool operator!=(const const_iterator& __it) const { return _M_cur != __it._M_cur; } }; // Note: assumes long is at least 32 bits. enum { _S_num_primes = 29 }; template struct _Hashtable_prime_list { static const _PrimeType __stl_prime_list[_S_num_primes]; static const _PrimeType* _S_get_prime_list(); }; template const _PrimeType _Hashtable_prime_list<_PrimeType>::__stl_prime_list[_S_num_primes] = { 5ul, 53ul, 97ul, 193ul, 389ul, 769ul, 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, 1610612741ul, 3221225473ul, 4294967291ul }; template inline const _PrimeType* _Hashtable_prime_list<_PrimeType>::_S_get_prime_list() { return __stl_prime_list; } inline unsigned long __stl_next_prime(unsigned long __n) { const unsigned long* __first = _Hashtable_prime_list::_S_get_prime_list(); const unsigned long* __last = __first + (int)_S_num_primes; const unsigned long* pos = std::lower_bound(__first, __last, __n); return pos == __last ? *(__last - 1) : *pos; } // Forward declaration of operator==. template class hashtable; template bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2); // Hashtables handle allocators a bit differently than other // containers do. If we're using standard-conforming allocators, then // a hashtable unconditionally has a member variable to hold its // allocator, even if it so happens that all instances of the // allocator type are identical. This is because, for hashtables, // this extra storage is negligible. Additionally, a base class // wouldn't serve any other purposes; it wouldn't, for example, // simplify the exception-handling code. template class hashtable { public: typedef _Key key_type; typedef _Val value_type; typedef _HashFcn hasher; typedef _EqualKey key_equal; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; hasher hash_funct() const { return _M_hash; } key_equal key_eq() const { return _M_equals; } private: typedef _Hashtable_node<_Val> _Node; public: typedef typename _Alloc::template rebind::other allocator_type; allocator_type get_allocator() const { return _M_node_allocator; } private: typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc; typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc; typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type; _Node_Alloc _M_node_allocator; _Node* _M_get_node() { return _M_node_allocator.allocate(1); } void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); } private: hasher _M_hash; key_equal _M_equals; _ExtractKey _M_get_key; _Vector_type _M_buckets; size_type _M_num_elements; public: typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> iterator; typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> const_iterator; friend struct _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>; friend struct _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>; public: hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql, const _ExtractKey& __ext, const allocator_type& __a = allocator_type()) : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), _M_get_key(__ext), _M_buckets(__a), _M_num_elements(0) { _M_initialize_buckets(__n); } hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql, const allocator_type& __a = allocator_type()) : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), _M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0) { _M_initialize_buckets(__n); } hashtable(const hashtable& __ht) : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash), _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key), _M_buckets(__ht.get_allocator()), _M_num_elements(0) { _M_copy_from(__ht); } hashtable& operator= (const hashtable& __ht) { if (&__ht != this) { clear(); _M_hash = __ht._M_hash; _M_equals = __ht._M_equals; _M_get_key = __ht._M_get_key; _M_copy_from(__ht); } return *this; } ~hashtable() { clear(); } size_type size() const { return _M_num_elements; } size_type max_size() const { return size_type(-1); } bool empty() const { return size() == 0; } void swap(hashtable& __ht) { std::swap(_M_hash, __ht._M_hash); std::swap(_M_equals, __ht._M_equals); std::swap(_M_get_key, __ht._M_get_key); _M_buckets.swap(__ht._M_buckets); std::swap(_M_num_elements, __ht._M_num_elements); } iterator begin() { for (size_type __n = 0; __n < _M_buckets.size(); ++__n) if (_M_buckets[__n]) return iterator(_M_buckets[__n], this); return end(); } iterator end() { return iterator(0, this); } const_iterator begin() const { for (size_type __n = 0; __n < _M_buckets.size(); ++__n) if (_M_buckets[__n]) return const_iterator(_M_buckets[__n], this); return end(); } const_iterator end() const { return const_iterator(0, this); } template friend bool operator==(const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); public: size_type bucket_count() const { return _M_buckets.size(); } size_type max_bucket_count() const { return _Hashtable_prime_list:: _S_get_prime_list()[(int)_S_num_primes - 1]; } size_type elems_in_bucket(size_type __bucket) const { size_type __result = 0; for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next) __result += 1; return __result; } pair insert_unique(const value_type& __obj) { resize(_M_num_elements + 1); return insert_unique_noresize(__obj); } iterator insert_equal(const value_type& __obj) { resize(_M_num_elements + 1); return insert_equal_noresize(__obj); } pair insert_unique_noresize(const value_type& __obj); iterator insert_equal_noresize(const value_type& __obj); template void insert_unique(_InputIterator __f, _InputIterator __l) { insert_unique(__f, __l, __iterator_category(__f)); } template void insert_equal(_InputIterator __f, _InputIterator __l) { insert_equal(__f, __l, __iterator_category(__f)); } template void insert_unique(_InputIterator __f, _InputIterator __l, input_iterator_tag) { for ( ; __f != __l; ++__f) insert_unique(*__f); } template void insert_equal(_InputIterator __f, _InputIterator __l, input_iterator_tag) { for ( ; __f != __l; ++__f) insert_equal(*__f); } template void insert_unique(_ForwardIterator __f, _ForwardIterator __l, forward_iterator_tag) { size_type __n = distance(__f, __l); resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_unique_noresize(*__f); } template void insert_equal(_ForwardIterator __f, _ForwardIterator __l, forward_iterator_tag) { size_type __n = distance(__f, __l); resize(_M_num_elements + __n); for ( ; __n > 0; --__n, ++__f) insert_equal_noresize(*__f); } reference find_or_insert(const value_type& __obj); iterator find(const key_type& __key) { size_type __n = _M_bkt_num_key(__key); _Node* __first; for (__first = _M_buckets[__n]; __first && !_M_equals(_M_get_key(__first->_M_val), __key); __first = __first->_M_next) { } return iterator(__first, this); } const_iterator find(const key_type& __key) const { size_type __n = _M_bkt_num_key(__key); const _Node* __first; for (__first = _M_buckets[__n]; __first && !_M_equals(_M_get_key(__first->_M_val), __key); __first = __first->_M_next) { } return const_iterator(__first, this); } size_type count(const key_type& __key) const { const size_type __n = _M_bkt_num_key(__key); size_type __result = 0; for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next) if (_M_equals(_M_get_key(__cur->_M_val), __key)) ++__result; return __result; } pair equal_range(const key_type& __key); pair equal_range(const key_type& __key) const; size_type erase(const key_type& __key); void erase(const iterator& __it); void erase(iterator __first, iterator __last); void erase(const const_iterator& __it); void erase(const_iterator __first, const_iterator __last); void resize(size_type __num_elements_hint); void clear(); private: size_type _M_next_size(size_type __n) const { return __stl_next_prime(__n); } void _M_initialize_buckets(size_type __n) { const size_type __n_buckets = _M_next_size(__n); _M_buckets.reserve(__n_buckets); _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); _M_num_elements = 0; } size_type _M_bkt_num_key(const key_type& __key) const { return _M_bkt_num_key(__key, _M_buckets.size()); } size_type _M_bkt_num(const value_type& __obj) const { return _M_bkt_num_key(_M_get_key(__obj)); } size_type _M_bkt_num_key(const key_type& __key, size_t __n) const { return _M_hash(__key) % __n; } size_type _M_bkt_num(const value_type& __obj, size_t __n) const { return _M_bkt_num_key(_M_get_key(__obj), __n); } _Node* _M_new_node(const value_type& __obj) { _Node* __n = _M_get_node(); __n->_M_next = 0; __try { this->get_allocator().construct(&__n->_M_val, __obj); return __n; } __catch(...) { _M_put_node(__n); __throw_exception_again; } } void _M_delete_node(_Node* __n) { this->get_allocator().destroy(&__n->_M_val); _M_put_node(__n); } void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); void _M_erase_bucket(const size_type __n, _Node* __last); void _M_copy_from(const hashtable& __ht); }; template _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: operator++() { const _Node* __old = _M_cur; _M_cur = _M_cur->_M_next; if (!_M_cur) { size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) _M_cur = _M_ht->_M_buckets[__bucket]; } return *this; } template inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: operator++(int) { iterator __tmp = *this; ++*this; return __tmp; } template _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: operator++() { const _Node* __old = _M_cur; _M_cur = _M_cur->_M_next; if (!_M_cur) { size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) _M_cur = _M_ht->_M_buckets[__bucket]; } return *this; } template inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: operator++(int) { const_iterator __tmp = *this; ++*this; return __tmp; } template bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) { typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node; if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) return false; for (size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n) { _Node* __cur1 = __ht1._M_buckets[__n]; _Node* __cur2 = __ht2._M_buckets[__n]; // Check same length of lists for (; __cur1 && __cur2; __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) { } if (__cur1 || __cur2) return false; // Now check one's elements are in the other for (__cur1 = __ht1._M_buckets[__n] ; __cur1; __cur1 = __cur1->_M_next) { bool _found__cur1 = false; for (__cur2 = __ht2._M_buckets[__n]; __cur2; __cur2 = __cur2->_M_next) { if (__cur1->_M_val == __cur2->_M_val) { _found__cur1 = true; break; } } if (!_found__cur1) return false; } } return true; } template inline bool operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) { return !(__ht1 == __ht2); } template inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) { __ht1.swap(__ht2); } template pair::iterator, bool> hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: insert_unique_noresize(const value_type& __obj) { const size_type __n = _M_bkt_num(__obj); _Node* __first = _M_buckets[__n]; for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) return pair(iterator(__cur, this), false); _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements; return pair(iterator(__tmp, this), true); } template typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: insert_equal_noresize(const value_type& __obj) { const size_type __n = _M_bkt_num(__obj); _Node* __first = _M_buckets[__n]; for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) { _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __cur->_M_next; __cur->_M_next = __tmp; ++_M_num_elements; return iterator(__tmp, this); } _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements; return iterator(__tmp, this); } template typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: find_or_insert(const value_type& __obj) { resize(_M_num_elements + 1); size_type __n = _M_bkt_num(__obj); _Node* __first = _M_buckets[__n]; for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) return __cur->_M_val; _Node* __tmp = _M_new_node(__obj); __tmp->_M_next = __first; _M_buckets[__n] = __tmp; ++_M_num_elements; return __tmp->_M_val; } template pair::iterator, typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator> hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: equal_range(const key_type& __key) { typedef pair _Pii; const size_type __n = _M_bkt_num_key(__key); for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next) if (_M_equals(_M_get_key(__first->_M_val), __key)) { for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) if (!_M_equals(_M_get_key(__cur->_M_val), __key)) return _Pii(iterator(__first, this), iterator(__cur, this)); for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) if (_M_buckets[__m]) return _Pii(iterator(__first, this), iterator(_M_buckets[__m], this)); return _Pii(iterator(__first, this), end()); } return _Pii(end(), end()); } template pair::const_iterator, typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator> hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: equal_range(const key_type& __key) const { typedef pair _Pii; const size_type __n = _M_bkt_num_key(__key); for (const _Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next) { if (_M_equals(_M_get_key(__first->_M_val), __key)) { for (const _Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) if (!_M_equals(_M_get_key(__cur->_M_val), __key)) return _Pii(const_iterator(__first, this), const_iterator(__cur, this)); for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) if (_M_buckets[__m]) return _Pii(const_iterator(__first, this), const_iterator(_M_buckets[__m], this)); return _Pii(const_iterator(__first, this), end()); } } return _Pii(end(), end()); } template typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: erase(const key_type& __key) { const size_type __n = _M_bkt_num_key(__key); _Node* __first = _M_buckets[__n]; _Node* __saved_slot = 0; size_type __erased = 0; if (__first) { _Node* __cur = __first; _Node* __next = __cur->_M_next; while (__next) { if (_M_equals(_M_get_key(__next->_M_val), __key)) { if (&_M_get_key(__next->_M_val) != &__key) { __cur->_M_next = __next->_M_next; _M_delete_node(__next); __next = __cur->_M_next; ++__erased; --_M_num_elements; } else { __saved_slot = __cur; __cur = __next; __next = __cur->_M_next; } } else { __cur = __next; __next = __cur->_M_next; } } bool __delete_first = _M_equals(_M_get_key(__first->_M_val), __key); if (__saved_slot) { __next = __saved_slot->_M_next; __saved_slot->_M_next = __next->_M_next; _M_delete_node(__next); ++__erased; --_M_num_elements; } if (__delete_first) { _M_buckets[__n] = __first->_M_next; _M_delete_node(__first); ++__erased; --_M_num_elements; } } return __erased; } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: erase(const iterator& __it) { _Node* __p = __it._M_cur; if (__p) { const size_type __n = _M_bkt_num(__p->_M_val); _Node* __cur = _M_buckets[__n]; if (__cur == __p) { _M_buckets[__n] = __cur->_M_next; _M_delete_node(__cur); --_M_num_elements; } else { _Node* __next = __cur->_M_next; while (__next) { if (__next == __p) { __cur->_M_next = __next->_M_next; _M_delete_node(__next); --_M_num_elements; break; } else { __cur = __next; __next = __cur->_M_next; } } } } } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: erase(iterator __first, iterator __last) { size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); if (__first._M_cur == __last._M_cur) return; else if (__f_bucket == __l_bucket) _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); else { _M_erase_bucket(__f_bucket, __first._M_cur, 0); for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) _M_erase_bucket(__n, 0); if (__l_bucket != _M_buckets.size()) _M_erase_bucket(__l_bucket, __last._M_cur); } } template inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: erase(const_iterator __first, const_iterator __last) { erase(iterator(const_cast<_Node*>(__first._M_cur), const_cast(__first._M_ht)), iterator(const_cast<_Node*>(__last._M_cur), const_cast(__last._M_ht))); } template inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: erase(const const_iterator& __it) { erase(iterator(const_cast<_Node*>(__it._M_cur), const_cast(__it._M_ht))); } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: resize(size_type __num_elements_hint) { const size_type __old_n = _M_buckets.size(); if (__num_elements_hint > __old_n) { const size_type __n = _M_next_size(__num_elements_hint); if (__n > __old_n) { _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); __try { for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) { _Node* __first = _M_buckets[__bucket]; while (__first) { size_type __new_bucket = _M_bkt_num(__first->_M_val, __n); _M_buckets[__bucket] = __first->_M_next; __first->_M_next = __tmp[__new_bucket]; __tmp[__new_bucket] = __first; __first = _M_buckets[__bucket]; } } _M_buckets.swap(__tmp); } __catch(...) { for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) { while (__tmp[__bucket]) { _Node* __next = __tmp[__bucket]->_M_next; _M_delete_node(__tmp[__bucket]); __tmp[__bucket] = __next; } } __throw_exception_again; } } } } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) { _Node* __cur = _M_buckets[__n]; if (__cur == __first) _M_erase_bucket(__n, __last); else { _Node* __next; for (__next = __cur->_M_next; __next != __first; __cur = __next, __next = __cur->_M_next) ; while (__next != __last) { __cur->_M_next = __next->_M_next; _M_delete_node(__next); __next = __cur->_M_next; --_M_num_elements; } } } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: _M_erase_bucket(const size_type __n, _Node* __last) { _Node* __cur = _M_buckets[__n]; while (__cur != __last) { _Node* __next = __cur->_M_next; _M_delete_node(__cur); __cur = __next; _M_buckets[__n] = __cur; --_M_num_elements; } } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: clear() { if (_M_num_elements == 0) return; for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { _Node* __cur = _M_buckets[__i]; while (__cur != 0) { _Node* __next = __cur->_M_next; _M_delete_node(__cur); __cur = __next; } _M_buckets[__i] = 0; } _M_num_elements = 0; } template void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: _M_copy_from(const hashtable& __ht) { _M_buckets.clear(); _M_buckets.reserve(__ht._M_buckets.size()); _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); __try { for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { const _Node* __cur = __ht._M_buckets[__i]; if (__cur) { _Node* __local_copy = _M_new_node(__cur->_M_val); _M_buckets[__i] = __local_copy; for (_Node* __next = __cur->_M_next; __next; __cur = __next, __next = __cur->_M_next) { __local_copy->_M_next = _M_new_node(__next->_M_val); __local_copy = __local_copy->_M_next; } } } _M_num_elements = __ht._M_num_elements; } __catch(...) { clear(); __throw_exception_again; } } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/backward/backward_warning.h000064400000004673152526447510012172 0ustar00// Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file backward/backward_warning.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iosfwd} */ #ifndef _BACKWARD_BACKWARD_WARNING_H #define _BACKWARD_BACKWARD_WARNING_H 1 #ifdef __DEPRECATED #warning \ This file includes at least one deprecated or antiquated header which \ may be removed without further notice at a future date. Please use a \ non-deprecated interface with equivalent functionality instead. For a \ listing of replacement headers and interfaces, consult the file \ backward_warning.h. To disable this warning use -Wno-deprecated. /* A list of valid replacements is as follows: Use: Instead of: , basic_stringbuf , strstreambuf , basic_istringstream , istrstream , basic_ostringstream , ostrstream , basic_stringstream , strstream , unordered_set , hash_set , unordered_multiset , hash_multiset , unordered_map , hash_map , unordered_multimap , hash_multimap , bind , binder1st , bind , binder2nd , bind , bind1st , bind , bind2nd , unique_ptr , auto_ptr */ #endif #endif 8/backward/auto_ptr.h000064400000025064152526447510010521 0ustar00// auto_ptr implementation -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file backward/auto_ptr.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _BACKWARD_AUTO_PTR_H #define _BACKWARD_AUTO_PTR_H 1 #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * A wrapper class to provide auto_ptr with reference semantics. * For example, an auto_ptr can be assigned (or constructed from) * the result of a function which returns an auto_ptr by value. * * All the auto_ptr_ref stuff should happen behind the scenes. */ template struct auto_ptr_ref { _Tp1* _M_ptr; explicit auto_ptr_ref(_Tp1* __p): _M_ptr(__p) { } } _GLIBCXX_DEPRECATED; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" /** * @brief A simple smart pointer providing strict ownership semantics. * * The Standard says: *
   *  An @c auto_ptr owns the object it holds a pointer to.  Copying
   *  an @c auto_ptr copies the pointer and transfers ownership to the
   *  destination.  If more than one @c auto_ptr owns the same object
   *  at the same time the behavior of the program is undefined.
   *
   *  The uses of @c auto_ptr include providing temporary
   *  exception-safety for dynamically allocated memory, passing
   *  ownership of dynamically allocated memory to a function, and
   *  returning dynamically allocated memory from a function.  @c
   *  auto_ptr does not meet the CopyConstructible and Assignable
   *  requirements for Standard Library container elements and thus
   *  instantiating a Standard Library container with an @c auto_ptr
   *  results in undefined behavior.
   *  
* Quoted from [20.4.5]/3. * * Good examples of what can and cannot be done with auto_ptr can * be found in the libstdc++ testsuite. * * _GLIBCXX_RESOLVE_LIB_DEFECTS * 127. auto_ptr<> conversion issues * These resolutions have all been incorporated. */ template class auto_ptr { private: _Tp* _M_ptr; public: /// The pointed-to type. typedef _Tp element_type; /** * @brief An %auto_ptr is usually constructed from a raw pointer. * @param __p A pointer (defaults to NULL). * * This object now @e owns the object pointed to by @a __p. */ explicit auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { } /** * @brief An %auto_ptr can be constructed from another %auto_ptr. * @param __a Another %auto_ptr of the same type. * * This object now @e owns the object previously owned by @a __a, * which has given up ownership. */ auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { } /** * @brief An %auto_ptr can be constructed from another %auto_ptr. * @param __a Another %auto_ptr of a different but related type. * * A pointer-to-Tp1 must be convertible to a * pointer-to-Tp/element_type. * * This object now @e owns the object previously owned by @a __a, * which has given up ownership. */ template auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { } /** * @brief %auto_ptr assignment operator. * @param __a Another %auto_ptr of the same type. * * This object now @e owns the object previously owned by @a __a, * which has given up ownership. The object that this one @e * used to own and track has been deleted. */ auto_ptr& operator=(auto_ptr& __a) throw() { reset(__a.release()); return *this; } /** * @brief %auto_ptr assignment operator. * @param __a Another %auto_ptr of a different but related type. * * A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type. * * This object now @e owns the object previously owned by @a __a, * which has given up ownership. The object that this one @e * used to own and track has been deleted. */ template auto_ptr& operator=(auto_ptr<_Tp1>& __a) throw() { reset(__a.release()); return *this; } /** * When the %auto_ptr goes out of scope, the object it owns is * deleted. If it no longer owns anything (i.e., @c get() is * @c NULL), then this has no effect. * * The C++ standard says there is supposed to be an empty throw * specification here, but omitting it is standard conforming. Its * presence can be detected only if _Tp::~_Tp() throws, but this is * prohibited. [17.4.3.6]/2 */ ~auto_ptr() { delete _M_ptr; } /** * @brief Smart pointer dereferencing. * * If this %auto_ptr no longer owns anything, then this * operation will crash. (For a smart pointer, no longer owns * anything is the same as being a null pointer, and you know * what happens when you dereference one of those...) */ element_type& operator*() const throw() { __glibcxx_assert(_M_ptr != 0); return *_M_ptr; } /** * @brief Smart pointer dereferencing. * * This returns the pointer itself, which the language then will * automatically cause to be dereferenced. */ element_type* operator->() const throw() { __glibcxx_assert(_M_ptr != 0); return _M_ptr; } /** * @brief Bypassing the smart pointer. * @return The raw pointer being managed. * * You can get a copy of the pointer that this object owns, for * situations such as passing to a function which only accepts * a raw pointer. * * @note This %auto_ptr still owns the memory. */ element_type* get() const throw() { return _M_ptr; } /** * @brief Bypassing the smart pointer. * @return The raw pointer being managed. * * You can get a copy of the pointer that this object owns, for * situations such as passing to a function which only accepts * a raw pointer. * * @note This %auto_ptr no longer owns the memory. When this object * goes out of scope, nothing will happen. */ element_type* release() throw() { element_type* __tmp = _M_ptr; _M_ptr = 0; return __tmp; } /** * @brief Forcibly deletes the managed object. * @param __p A pointer (defaults to NULL). * * This object now @e owns the object pointed to by @a __p. The * previous object has been deleted. */ void reset(element_type* __p = 0) throw() { if (__p != _M_ptr) { delete _M_ptr; _M_ptr = __p; } } /** * @brief Automatic conversions * * These operations are supposed to convert an %auto_ptr into and from * an auto_ptr_ref automatically as needed. This would allow * constructs such as * @code * auto_ptr func_returning_auto_ptr(.....); * ... * auto_ptr ptr = func_returning_auto_ptr(.....); * @endcode * * But it doesn't work, and won't be fixed. For further details see * http://cplusplus.github.io/LWG/lwg-closed.html#463 */ auto_ptr(auto_ptr_ref __ref) throw() : _M_ptr(__ref._M_ptr) { } auto_ptr& operator=(auto_ptr_ref __ref) throw() { if (__ref._M_ptr != this->get()) { delete _M_ptr; _M_ptr = __ref._M_ptr; } return *this; } template operator auto_ptr_ref<_Tp1>() throw() { return auto_ptr_ref<_Tp1>(this->release()); } template operator auto_ptr<_Tp1>() throw() { return auto_ptr<_Tp1>(this->release()); } } _GLIBCXX_DEPRECATED; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 541. shared_ptr template assignment and void template<> class auto_ptr { public: typedef void element_type; } _GLIBCXX_DEPRECATED; #if __cplusplus >= 201103L template<_Lock_policy _Lp> template inline __shared_count<_Lp>::__shared_count(std::auto_ptr<_Tp>&& __r) : _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get())) { __r.release(); } template template inline __shared_ptr<_Tp, _Lp>::__shared_ptr(std::auto_ptr<_Tp1>&& __r) : _M_ptr(__r.get()), _M_refcount() { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) static_assert( sizeof(_Tp1) > 0, "incomplete type" ); _Tp1* __tmp = __r.get(); _M_refcount = __shared_count<_Lp>(std::move(__r)); _M_enable_shared_from_this_with(__tmp); } template template inline shared_ptr<_Tp>::shared_ptr(std::auto_ptr<_Tp1>&& __r) : __shared_ptr<_Tp>(std::move(__r)) { } template template inline unique_ptr<_Tp, _Dp>::unique_ptr(auto_ptr<_Up>&& __u) noexcept : _M_t(__u.release(), deleter_type()) { } #endif #pragma GCC diagnostic pop _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _BACKWARD_AUTO_PTR_H */ 8/backward/binders.h000064400000015777152526447510010324 0ustar00// Functor implementations -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file backward/binders.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{functional} */ #ifndef _BACKWARD_BINDERS_H #define _BACKWARD_BINDERS_H 1 // Suppress deprecated warning for this file. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // 20.3.6 binders /** @defgroup binders Binder Classes * @ingroup functors * * Binders turn functions/functors with two arguments into functors * with a single argument, storing an argument to be applied later. * For example, a variable @c B of type @c binder1st is constructed * from a functor @c f and an argument @c x. Later, B's @c * operator() is called with a single argument @c y. The return * value is the value of @c f(x,y). @c B can be @a called with * various arguments (y1, y2, ...) and will in turn call @c * f(x,y1), @c f(x,y2), ... * * The function @c bind1st is provided to save some typing. It takes the * function and an argument as parameters, and returns an instance of * @c binder1st. * * The type @c binder2nd and its creator function @c bind2nd do the same * thing, but the stored argument is passed as the second parameter instead * of the first, e.g., @c bind2nd(std::minus(),1.3) will create a * functor whose @c operator() accepts a floating-point number, subtracts * 1.3 from it, and returns the result. (If @c bind1st had been used, * the functor would perform 1.3 - x instead. * * Creator-wrapper functions like @c bind1st are intended to be used in * calling algorithms. Their return values will be temporary objects. * (The goal is to not require you to type names like * @c std::binder1st> for declaring a variable to hold the * return value from @c bind1st(std::plus(),5). * * These become more useful when combined with the composition functions. * * These functions are deprecated in C++11 and can be replaced by * @c std::bind (or @c std::tr1::bind) which is more powerful and flexible, * supporting functions with any number of arguments. Uses of @c bind1st * can be replaced by @c std::bind(f, x, std::placeholders::_1) and * @c bind2nd by @c std::bind(f, std::placeholders::_1, x). * @{ */ /// One of the @link binders binder functors@endlink. template class binder1st : public unary_function { protected: _Operation op; typename _Operation::first_argument_type value; public: binder1st(const _Operation& __x, const typename _Operation::first_argument_type& __y) : op(__x), value(__y) { } typename _Operation::result_type operator()(const typename _Operation::second_argument_type& __x) const { return op(value, __x); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 109. Missing binders for non-const sequence elements typename _Operation::result_type operator()(typename _Operation::second_argument_type& __x) const { return op(value, __x); } } _GLIBCXX_DEPRECATED; /// One of the @link binders binder functors@endlink. template inline binder1st<_Operation> bind1st(const _Operation& __fn, const _Tp& __x) { typedef typename _Operation::first_argument_type _Arg1_type; return binder1st<_Operation>(__fn, _Arg1_type(__x)); } /// One of the @link binders binder functors@endlink. template class binder2nd : public unary_function { protected: _Operation op; typename _Operation::second_argument_type value; public: binder2nd(const _Operation& __x, const typename _Operation::second_argument_type& __y) : op(__x), value(__y) { } typename _Operation::result_type operator()(const typename _Operation::first_argument_type& __x) const { return op(__x, value); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 109. Missing binders for non-const sequence elements typename _Operation::result_type operator()(typename _Operation::first_argument_type& __x) const { return op(__x, value); } } _GLIBCXX_DEPRECATED; /// One of the @link binders binder functors@endlink. template inline binder2nd<_Operation> bind2nd(const _Operation& __fn, const _Tp& __x) { typedef typename _Operation::second_argument_type _Arg2_type; return binder2nd<_Operation>(__fn, _Arg2_type(__x)); } /** @} */ _GLIBCXX_END_NAMESPACE_VERSION } // namespace #pragma GCC diagnostic pop #endif /* _BACKWARD_BINDERS_H */ 8/backward/strstream000064400000013246152526447510010461 0ustar00// Backward-compat support -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * Copyright (c) 1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ // WARNING: The classes defined in this header are DEPRECATED. This // header is defined in section D.7.1 of the C++ standard, and it // MAY BE REMOVED in a future standard revision. One should use the // header instead. /** @file strstream * This is a Standard C++ Library header. */ #ifndef _BACKWARD_STRSTREAM #define _BACKWARD_STRSTREAM #include "backward_warning.h" #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Class strstreambuf, a streambuf class that manages an array of char. // Note that this class is not a template. class strstreambuf : public basic_streambuf > { public: // Types. typedef char_traits _Traits; typedef basic_streambuf _Base; public: // Constructor, destructor explicit strstreambuf(streamsize __initial_capacity = 0); strstreambuf(void* (*__alloc)(size_t), void (*__free)(void*)); strstreambuf(char* __get, streamsize __n, char* __put = 0) throw (); strstreambuf(signed char* __get, streamsize __n, signed char* __put = 0) throw (); strstreambuf(unsigned char* __get, streamsize __n, unsigned char* __put=0) throw (); strstreambuf(const char* __get, streamsize __n) throw (); strstreambuf(const signed char* __get, streamsize __n) throw (); strstreambuf(const unsigned char* __get, streamsize __n) throw (); virtual ~strstreambuf(); public: void freeze(bool = true) throw (); char* str() throw (); _GLIBCXX_PURE int pcount() const throw (); protected: virtual int_type overflow(int_type __c = _Traits::eof()); virtual int_type pbackfail(int_type __c = _Traits::eof()); virtual int_type underflow(); virtual _Base* setbuf(char* __buf, streamsize __n); virtual pos_type seekoff(off_type __off, ios_base::seekdir __dir, ios_base::openmode __mode = ios_base::in | ios_base::out); virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode = ios_base::in | ios_base::out); private: strstreambuf& operator=(const strstreambuf&); strstreambuf(const strstreambuf&); // Dynamic allocation, possibly using _M_alloc_fun and _M_free_fun. char* _M_alloc(size_t); void _M_free(char*); // Helper function used in constructors. void _M_setup(char* __get, char* __put, streamsize __n) throw (); private: // Data members. void* (*_M_alloc_fun)(size_t); void (*_M_free_fun)(void*); bool _M_dynamic : 1; bool _M_frozen : 1; bool _M_constant : 1; }; // Class istrstream, an istream that manages a strstreambuf. class istrstream : public basic_istream { public: explicit istrstream(char*); explicit istrstream(const char*); istrstream(char* , streamsize); istrstream(const char*, streamsize); virtual ~istrstream(); _GLIBCXX_CONST strstreambuf* rdbuf() const throw (); char* str() throw (); private: strstreambuf _M_buf; }; // Class ostrstream class ostrstream : public basic_ostream { public: ostrstream(); ostrstream(char*, int, ios_base::openmode = ios_base::out); virtual ~ostrstream(); _GLIBCXX_CONST strstreambuf* rdbuf() const throw (); void freeze(bool = true) throw(); char* str() throw (); _GLIBCXX_PURE int pcount() const throw (); private: strstreambuf _M_buf; }; // Class strstream class strstream : public basic_iostream { public: typedef char char_type; typedef char_traits::int_type int_type; typedef char_traits::pos_type pos_type; typedef char_traits::off_type off_type; strstream(); strstream(char*, int, ios_base::openmode = ios_base::in | ios_base::out); virtual ~strstream(); _GLIBCXX_CONST strstreambuf* rdbuf() const throw (); void freeze(bool = true) throw (); _GLIBCXX_PURE int pcount() const throw (); char* str() throw (); private: strstreambuf _M_buf; }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/backward/hash_map000064400000042557152526447510010224 0ustar00// Hashing map implementation -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * Copyright (c) 1996 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ /** @file backward/hash_map * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _BACKWARD_HASH_MAP #define _BACKWARD_HASH_MAP 1 #ifndef _GLIBCXX_PERMIT_BACKWARD_HASH #include "backward_warning.h" #endif #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::equal_to; using std::allocator; using std::pair; using std::_Select1st; /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template, class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > class hash_map { private: typedef hashtable,_Key, _HashFn, _Select1st >, _EqualKey, _Alloc> _Ht; _Ht _M_ht; public: typedef typename _Ht::key_type key_type; typedef _Tp data_type; typedef _Tp mapped_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Ht::pointer pointer; typedef typename _Ht::const_pointer const_pointer; typedef typename _Ht::reference reference; typedef typename _Ht::const_reference const_reference; typedef typename _Ht::iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_map(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_map(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} template hash_map(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_map(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_map(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_map(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_unique(__f, __l); } size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); } template friend bool operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&, const hash_map<_K1, _T1, _HF, _EqK, _Al>&); iterator begin() { return _M_ht.begin(); } iterator end() { return _M_ht.end(); } const_iterator begin() const { return _M_ht.begin(); } const_iterator end() const { return _M_ht.end(); } pair insert(const value_type& __obj) { return _M_ht.insert_unique(__obj); } template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f, __l); } pair insert_noresize(const value_type& __obj) { return _M_ht.insert_unique_noresize(__obj); } iterator find(const key_type& __key) { return _M_ht.find(__key); } const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } _Tp& operator[](const key_type& __key) { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; } size_type count(const key_type& __key) const { return _M_ht.count(__key); } pair equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } size_type erase(const key_type& __key) {return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } void clear() { _M_ht.clear(); } void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template inline bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) { return __hm1._M_ht == __hm2._M_ht; } template inline bool operator!=(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) { return !(__hm1 == __hm2); } template inline void swap(hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) { __hm1.swap(__hm2); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template, class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > class hash_multimap { // concept requirements __glibcxx_class_requires(_Key, _SGIAssignableConcept) __glibcxx_class_requires(_Tp, _SGIAssignableConcept) __glibcxx_class_requires3(_HashFn, size_t, _Key, _UnaryFunctionConcept) __glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept) private: typedef hashtable, _Key, _HashFn, _Select1st >, _EqualKey, _Alloc> _Ht; _Ht _M_ht; public: typedef typename _Ht::key_type key_type; typedef _Tp data_type; typedef _Tp mapped_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Ht::pointer pointer; typedef typename _Ht::const_pointer const_pointer; typedef typename _Ht::reference reference; typedef typename _Ht::const_reference const_reference; typedef typename _Ht::iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } hash_multimap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_multimap(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_multimap(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} template hash_multimap(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_equal(__f, __l); } size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); } template friend bool operator==(const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&, const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&); iterator begin() { return _M_ht.begin(); } iterator end() { return _M_ht.end(); } const_iterator begin() const { return _M_ht.begin(); } const_iterator end() const { return _M_ht.end(); } iterator insert(const value_type& __obj) { return _M_ht.insert_equal(__obj); } template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } iterator insert_noresize(const value_type& __obj) { return _M_ht.insert_equal_noresize(__obj); } iterator find(const key_type& __key) { return _M_ht.find(__key); } const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } pair equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } size_type erase(const key_type& __key) { return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } void clear() { _M_ht.clear(); } void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template inline bool operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) { return __hm1._M_ht == __hm2._M_ht; } template inline bool operator!=(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) { return !(__hm1 == __hm2); } template inline void swap(hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) { __hm1.swap(__hm2); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Specialization of insert_iterator so that it will work for hash_map // and hash_multimap. template class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> > { protected: typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container; _Container* container; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; template class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> > { protected: typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc> _Container; _Container* container; typename _Container::iterator iter; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/backward/hash_fun.h000064400000010230152526447510010444 0ustar00// 'struct hash' from SGI -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ /** @file backward/hash_fun.h * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _BACKWARD_HASH_FUN_H #define _BACKWARD_HASH_FUN_H 1 #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; template struct hash { }; inline size_t __stl_hash_string(const char* __s) { unsigned long __h = 0; for ( ; *__s; ++__s) __h = 5 * __h + *__s; return size_t(__h); } template<> struct hash { size_t operator()(const char* __s) const { return __stl_hash_string(__s); } }; template<> struct hash { size_t operator()(const char* __s) const { return __stl_hash_string(__s); } }; template<> struct hash { size_t operator()(char __x) const { return __x; } }; template<> struct hash { size_t operator()(unsigned char __x) const { return __x; } }; template<> struct hash { size_t operator()(unsigned char __x) const { return __x; } }; template<> struct hash { size_t operator()(short __x) const { return __x; } }; template<> struct hash { size_t operator()(unsigned short __x) const { return __x; } }; template<> struct hash { size_t operator()(int __x) const { return __x; } }; template<> struct hash { size_t operator()(unsigned int __x) const { return __x; } }; template<> struct hash { size_t operator()(long __x) const { return __x; } }; template<> struct hash { size_t operator()(unsigned long __x) const { return __x; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/system_error000064400000026402152526447510007412 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/system_error * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_SYSTEM_ERROR #define _GLIBCXX_SYSTEM_ERROR 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION class error_code; class error_condition; class system_error; /// is_error_code_enum template struct is_error_code_enum : public false_type { }; /// is_error_condition_enum template struct is_error_condition_enum : public false_type { }; template<> struct is_error_condition_enum : public true_type { }; #if __cplusplus > 201402L template inline constexpr bool is_error_code_enum_v = is_error_code_enum<_Tp>::value; template inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; #endif // C++17 inline namespace _V2 { /// error_category class error_category { public: constexpr error_category() noexcept = default; virtual ~error_category(); error_category(const error_category&) = delete; error_category& operator=(const error_category&) = delete; virtual const char* name() const noexcept = 0; // We need two different virtual functions here, one returning a // COW string and one returning an SSO string. Their positions in the // vtable must be consistent for dynamic dispatch to work, but which one // the name "message()" finds depends on which ABI the caller is using. #if _GLIBCXX_USE_CXX11_ABI private: _GLIBCXX_DEFAULT_ABI_TAG virtual __cow_string _M_message(int) const; public: _GLIBCXX_DEFAULT_ABI_TAG virtual string message(int) const = 0; #else virtual string message(int) const = 0; private: virtual __sso_string _M_message(int) const; #endif public: virtual error_condition default_error_condition(int __i) const noexcept; virtual bool equivalent(int __i, const error_condition& __cond) const noexcept; virtual bool equivalent(const error_code& __code, int __i) const noexcept; bool operator<(const error_category& __other) const noexcept { return less()(this, &__other); } bool operator==(const error_category& __other) const noexcept { return this == &__other; } bool operator!=(const error_category& __other) const noexcept { return this != &__other; } }; // DR 890. _GLIBCXX_CONST const error_category& system_category() noexcept; _GLIBCXX_CONST const error_category& generic_category() noexcept; } // end inline namespace error_code make_error_code(errc) noexcept; template struct hash; /// error_code // Implementation-specific error identification struct error_code { error_code() noexcept : _M_value(0), _M_cat(&system_category()) { } error_code(int __v, const error_category& __cat) noexcept : _M_value(__v), _M_cat(&__cat) { } template::value>::type> error_code(_ErrorCodeEnum __e) noexcept { *this = make_error_code(__e); } void assign(int __v, const error_category& __cat) noexcept { _M_value = __v; _M_cat = &__cat; } void clear() noexcept { assign(0, system_category()); } // DR 804. template typename enable_if::value, error_code&>::type operator=(_ErrorCodeEnum __e) noexcept { return *this = make_error_code(__e); } int value() const noexcept { return _M_value; } const error_category& category() const noexcept { return *_M_cat; } error_condition default_error_condition() const noexcept; _GLIBCXX_DEFAULT_ABI_TAG string message() const { return category().message(value()); } explicit operator bool() const noexcept { return _M_value != 0; } // DR 804. private: friend class hash; int _M_value; const error_category* _M_cat; }; // 19.4.2.6 non-member functions inline error_code make_error_code(errc __e) noexcept { return error_code(static_cast(__e), generic_category()); } inline bool operator<(const error_code& __lhs, const error_code& __rhs) noexcept { return (__lhs.category() < __rhs.category() || (__lhs.category() == __rhs.category() && __lhs.value() < __rhs.value())); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e) { return (__os << __e.category().name() << ':' << __e.value()); } error_condition make_error_condition(errc) noexcept; /// error_condition // Portable error identification struct error_condition { error_condition() noexcept : _M_value(0), _M_cat(&generic_category()) { } error_condition(int __v, const error_category& __cat) noexcept : _M_value(__v), _M_cat(&__cat) { } template::value>::type> error_condition(_ErrorConditionEnum __e) noexcept { *this = make_error_condition(__e); } void assign(int __v, const error_category& __cat) noexcept { _M_value = __v; _M_cat = &__cat; } // DR 804. template typename enable_if::value, error_condition&>::type operator=(_ErrorConditionEnum __e) noexcept { return *this = make_error_condition(__e); } void clear() noexcept { assign(0, generic_category()); } // 19.4.3.4 observers int value() const noexcept { return _M_value; } const error_category& category() const noexcept { return *_M_cat; } _GLIBCXX_DEFAULT_ABI_TAG string message() const { return category().message(value()); } explicit operator bool() const noexcept { return _M_value != 0; } // DR 804. private: int _M_value; const error_category* _M_cat; }; // 19.4.3.6 non-member functions inline error_condition make_error_condition(errc __e) noexcept { return error_condition(static_cast(__e), generic_category()); } inline bool operator<(const error_condition& __lhs, const error_condition& __rhs) noexcept { return (__lhs.category() < __rhs.category() || (__lhs.category() == __rhs.category() && __lhs.value() < __rhs.value())); } // 19.4.4 Comparison operators inline bool operator==(const error_code& __lhs, const error_code& __rhs) noexcept { return (__lhs.category() == __rhs.category() && __lhs.value() == __rhs.value()); } inline bool operator==(const error_code& __lhs, const error_condition& __rhs) noexcept { return (__lhs.category().equivalent(__lhs.value(), __rhs) || __rhs.category().equivalent(__lhs, __rhs.value())); } inline bool operator==(const error_condition& __lhs, const error_code& __rhs) noexcept { return (__rhs.category().equivalent(__rhs.value(), __lhs) || __lhs.category().equivalent(__rhs, __lhs.value())); } inline bool operator==(const error_condition& __lhs, const error_condition& __rhs) noexcept { return (__lhs.category() == __rhs.category() && __lhs.value() == __rhs.value()); } inline bool operator!=(const error_code& __lhs, const error_code& __rhs) noexcept { return !(__lhs == __rhs); } inline bool operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept { return !(__lhs == __rhs); } inline bool operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept { return !(__lhs == __rhs); } inline bool operator!=(const error_condition& __lhs, const error_condition& __rhs) noexcept { return !(__lhs == __rhs); } /** * @brief Thrown to indicate error code of underlying system. * * @ingroup exceptions */ class system_error : public std::runtime_error { private: error_code _M_code; public: system_error(error_code __ec = error_code()) : runtime_error(__ec.message()), _M_code(__ec) { } system_error(error_code __ec, const string& __what) : runtime_error(__what + ": " + __ec.message()), _M_code(__ec) { } system_error(error_code __ec, const char* __what) : runtime_error(__what + (": " + __ec.message())), _M_code(__ec) { } system_error(int __v, const error_category& __ecat, const char* __what) : system_error(error_code(__v, __ecat), __what) { } system_error(int __v, const error_category& __ecat) : runtime_error(error_code(__v, __ecat).message()), _M_code(__v, __ecat) { } system_error(int __v, const error_category& __ecat, const string& __what) : runtime_error(__what + ": " + error_code(__v, __ecat).message()), _M_code(__v, __ecat) { } virtual ~system_error() noexcept; const error_code& code() const noexcept { return _M_code; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifndef _GLIBCXX_COMPATIBILITY_CXX0X // DR 1182. /// std::hash specialization for error_code. template<> struct hash : public __hash_base { size_t operator()(const error_code& __e) const noexcept { const size_t __tmp = std::_Hash_impl::hash(__e._M_value); return std::_Hash_impl::__hash_combine(__e._M_cat, __tmp); } }; #endif // _GLIBCXX_COMPATIBILITY_CXX0X #if __cplusplus > 201402L // DR 2686. /// std::hash specialization for error_condition. template<> struct hash : public __hash_base { size_t operator()(const error_condition& __e) const noexcept { const size_t __tmp = std::_Hash_impl::hash(__e.value()); return std::_Hash_impl::__hash_combine(__e.category(), __tmp); } }; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #endif // _GLIBCXX_SYSTEM_ERROR 8/set000064400000004777152526447510005463 0ustar00// -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file include/set * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_SET #define _GLIBCXX_SET 1 #pragma GCC system_header #include #include #include #include #ifdef _GLIBCXX_DEBUG # include #endif #ifdef _GLIBCXX_PROFILE # include #endif #endif /* _GLIBCXX_SET */ 8/unordered_map000064400000003470152526447510007501 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/unordered_map * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_UNORDERED_MAP #define _GLIBCXX_UNORDERED_MAP 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #include // equal_to, _Identity, _Select1st #include #include #include #include #ifdef _GLIBCXX_DEBUG # include #endif #ifdef _GLIBCXX_PROFILE # include #endif #endif // C++11 #endif // _GLIBCXX_UNORDERED_MAP 8/queue000064400000004643152526447510006004 0ustar00// -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file include/queue * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_QUEUE #define _GLIBCXX_QUEUE 1 #pragma GCC system_header #include #include #include #include #include #endif /* _GLIBCXX_QUEUE */ 8/shared_mutex000064400000045721152526447510007352 0ustar00// -*- C++ -*- // Copyright (C) 2013-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/shared_mutex * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_SHARED_MUTEX #define _GLIBCXX_SHARED_MUTEX 1 #pragma GCC system_header #if __cplusplus >= 201402L #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @ingroup mutexes * @{ */ #ifdef _GLIBCXX_USE_C99_STDINT_TR1 #ifdef _GLIBCXX_HAS_GTHREADS #if __cplusplus >= 201703L #define __cpp_lib_shared_mutex 201505 class shared_mutex; #endif #define __cpp_lib_shared_timed_mutex 201402 class shared_timed_mutex; #if _GLIBCXX_USE_PTHREAD_RWLOCK_T /// A shared mutex type implemented using pthread_rwlock_t. class __shared_mutex_pthread { friend class shared_timed_mutex; #ifdef PTHREAD_RWLOCK_INITIALIZER pthread_rwlock_t _M_rwlock = PTHREAD_RWLOCK_INITIALIZER; public: __shared_mutex_pthread() = default; ~__shared_mutex_pthread() = default; #else pthread_rwlock_t _M_rwlock; public: __shared_mutex_pthread() { int __ret = pthread_rwlock_init(&_M_rwlock, NULL); if (__ret == ENOMEM) __throw_bad_alloc(); else if (__ret == EAGAIN) __throw_system_error(int(errc::resource_unavailable_try_again)); else if (__ret == EPERM) __throw_system_error(int(errc::operation_not_permitted)); // Errors not handled: EBUSY, EINVAL __glibcxx_assert(__ret == 0); } ~__shared_mutex_pthread() { int __ret __attribute((__unused__)) = pthread_rwlock_destroy(&_M_rwlock); // Errors not handled: EBUSY, EINVAL __glibcxx_assert(__ret == 0); } #endif __shared_mutex_pthread(const __shared_mutex_pthread&) = delete; __shared_mutex_pthread& operator=(const __shared_mutex_pthread&) = delete; void lock() { int __ret = pthread_rwlock_wrlock(&_M_rwlock); if (__ret == EDEADLK) __throw_system_error(int(errc::resource_deadlock_would_occur)); // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); } bool try_lock() { int __ret = pthread_rwlock_trywrlock(&_M_rwlock); if (__ret == EBUSY) return false; // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); return true; } void unlock() { int __ret __attribute((__unused__)) = pthread_rwlock_unlock(&_M_rwlock); // Errors not handled: EPERM, EBUSY, EINVAL __glibcxx_assert(__ret == 0); } // Shared ownership void lock_shared() { int __ret; // We retry if we exceeded the maximum number of read locks supported by // the POSIX implementation; this can result in busy-waiting, but this // is okay based on the current specification of forward progress // guarantees by the standard. do __ret = pthread_rwlock_rdlock(&_M_rwlock); while (__ret == EAGAIN); if (__ret == EDEADLK) __throw_system_error(int(errc::resource_deadlock_would_occur)); // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); } bool try_lock_shared() { int __ret = pthread_rwlock_tryrdlock(&_M_rwlock); // If the maximum number of read locks has been exceeded, we just fail // to acquire the lock. Unlike for lock(), we are not allowed to throw // an exception. if (__ret == EBUSY || __ret == EAGAIN) return false; // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); return true; } void unlock_shared() { unlock(); } void* native_handle() { return &_M_rwlock; } }; #endif #if ! (_GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK) /// A shared mutex type implemented using std::condition_variable. class __shared_mutex_cv { friend class shared_timed_mutex; // Based on Howard Hinnant's reference implementation from N2406. // The high bit of _M_state is the write-entered flag which is set to // indicate a writer has taken the lock or is queuing to take the lock. // The remaining bits are the count of reader locks. // // To take a reader lock, block on gate1 while the write-entered flag is // set or the maximum number of reader locks is held, then increment the // reader lock count. // To release, decrement the count, then if the write-entered flag is set // and the count is zero then signal gate2 to wake a queued writer, // otherwise if the maximum number of reader locks was held signal gate1 // to wake a reader. // // To take a writer lock, block on gate1 while the write-entered flag is // set, then set the write-entered flag to start queueing, then block on // gate2 while the number of reader locks is non-zero. // To release, unset the write-entered flag and signal gate1 to wake all // blocked readers and writers. // // This means that when no reader locks are held readers and writers get // equal priority. When one or more reader locks is held a writer gets // priority and no more reader locks can be taken while the writer is // queued. // Only locked when accessing _M_state or waiting on condition variables. mutex _M_mut; // Used to block while write-entered is set or reader count at maximum. condition_variable _M_gate1; // Used to block queued writers while reader count is non-zero. condition_variable _M_gate2; // The write-entered flag and reader count. unsigned _M_state; static constexpr unsigned _S_write_entered = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1); static constexpr unsigned _S_max_readers = ~_S_write_entered; // Test whether the write-entered flag is set. _M_mut must be locked. bool _M_write_entered() const { return _M_state & _S_write_entered; } // The number of reader locks currently held. _M_mut must be locked. unsigned _M_readers() const { return _M_state & _S_max_readers; } public: __shared_mutex_cv() : _M_state(0) {} ~__shared_mutex_cv() { __glibcxx_assert( _M_state == 0 ); } __shared_mutex_cv(const __shared_mutex_cv&) = delete; __shared_mutex_cv& operator=(const __shared_mutex_cv&) = delete; // Exclusive ownership void lock() { unique_lock __lk(_M_mut); // Wait until we can set the write-entered flag. _M_gate1.wait(__lk, [=]{ return !_M_write_entered(); }); _M_state |= _S_write_entered; // Then wait until there are no more readers. _M_gate2.wait(__lk, [=]{ return _M_readers() == 0; }); } bool try_lock() { unique_lock __lk(_M_mut, try_to_lock); if (__lk.owns_lock() && _M_state == 0) { _M_state = _S_write_entered; return true; } return false; } void unlock() { lock_guard __lk(_M_mut); __glibcxx_assert( _M_write_entered() ); _M_state = 0; // call notify_all() while mutex is held so that another thread can't // lock and unlock the mutex then destroy *this before we make the call. _M_gate1.notify_all(); } // Shared ownership void lock_shared() { unique_lock __lk(_M_mut); _M_gate1.wait(__lk, [=]{ return _M_state < _S_max_readers; }); ++_M_state; } bool try_lock_shared() { unique_lock __lk(_M_mut, try_to_lock); if (!__lk.owns_lock()) return false; if (_M_state < _S_max_readers) { ++_M_state; return true; } return false; } void unlock_shared() { lock_guard __lk(_M_mut); __glibcxx_assert( _M_readers() > 0 ); auto __prev = _M_state--; if (_M_write_entered()) { // Wake the queued writer if there are no more readers. if (_M_readers() == 0) _M_gate2.notify_one(); // No need to notify gate1 because we give priority to the queued // writer, and that writer will eventually notify gate1 after it // clears the write-entered flag. } else { // Wake any thread that was blocked on reader overflow. if (__prev == _S_max_readers) _M_gate1.notify_one(); } } }; #endif #if __cplusplus > 201402L /// The standard shared mutex type. class shared_mutex { public: shared_mutex() = default; ~shared_mutex() = default; shared_mutex(const shared_mutex&) = delete; shared_mutex& operator=(const shared_mutex&) = delete; // Exclusive ownership void lock() { _M_impl.lock(); } bool try_lock() { return _M_impl.try_lock(); } void unlock() { _M_impl.unlock(); } // Shared ownership void lock_shared() { _M_impl.lock_shared(); } bool try_lock_shared() { return _M_impl.try_lock_shared(); } void unlock_shared() { _M_impl.unlock_shared(); } #if _GLIBCXX_USE_PTHREAD_RWLOCK_T typedef void* native_handle_type; native_handle_type native_handle() { return _M_impl.native_handle(); } private: __shared_mutex_pthread _M_impl; #else private: __shared_mutex_cv _M_impl; #endif }; #endif // C++17 #if _GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK using __shared_timed_mutex_base = __shared_mutex_pthread; #else using __shared_timed_mutex_base = __shared_mutex_cv; #endif /// The standard shared timed mutex type. class shared_timed_mutex : private __shared_timed_mutex_base { using _Base = __shared_timed_mutex_base; // Must use the same clock as condition_variable for __shared_mutex_cv. typedef chrono::system_clock __clock_t; public: shared_timed_mutex() = default; ~shared_timed_mutex() = default; shared_timed_mutex(const shared_timed_mutex&) = delete; shared_timed_mutex& operator=(const shared_timed_mutex&) = delete; // Exclusive ownership void lock() { _Base::lock(); } bool try_lock() { return _Base::try_lock(); } void unlock() { _Base::unlock(); } template bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time) { return try_lock_until(__clock_t::now() + __rel_time); } // Shared ownership void lock_shared() { _Base::lock_shared(); } bool try_lock_shared() { return _Base::try_lock_shared(); } void unlock_shared() { _Base::unlock_shared(); } template bool try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time) { return try_lock_shared_until(__clock_t::now() + __rel_time); } #if _GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK // Exclusive ownership template bool try_lock_until(const chrono::time_point<__clock_t, _Duration>& __atime) { auto __s = chrono::time_point_cast(__atime); auto __ns = chrono::duration_cast(__atime - __s); __gthread_time_t __ts = { static_cast(__s.time_since_epoch().count()), static_cast(__ns.count()) }; int __ret = pthread_rwlock_timedwrlock(&_M_rwlock, &__ts); // On self-deadlock, we just fail to acquire the lock. Technically, // the program violated the precondition. if (__ret == ETIMEDOUT || __ret == EDEADLK) return false; // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); return true; } template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { // DR 887 - Sync unknown clock to known clock. const typename _Clock::time_point __c_entry = _Clock::now(); const __clock_t::time_point __s_entry = __clock_t::now(); const auto __delta = __abs_time - __c_entry; const auto __s_atime = __s_entry + __delta; return try_lock_until(__s_atime); } // Shared ownership template bool try_lock_shared_until(const chrono::time_point<__clock_t, _Duration>& __atime) { auto __s = chrono::time_point_cast(__atime); auto __ns = chrono::duration_cast(__atime - __s); __gthread_time_t __ts = { static_cast(__s.time_since_epoch().count()), static_cast(__ns.count()) }; int __ret; // Unlike for lock(), we are not allowed to throw an exception so if // the maximum number of read locks has been exceeded, or we would // deadlock, we just try to acquire the lock again (and will time out // eventually). // In cases where we would exceed the maximum number of read locks // throughout the whole time until the timeout, we will fail to // acquire the lock even if it would be logically free; however, this // is allowed by the standard, and we made a "strong effort" // (see C++14 30.4.1.4p26). // For cases where the implementation detects a deadlock we // intentionally block and timeout so that an early return isn't // mistaken for a spurious failure, which might help users realise // there is a deadlock. do __ret = pthread_rwlock_timedrdlock(&_M_rwlock, &__ts); while (__ret == EAGAIN || __ret == EDEADLK); if (__ret == ETIMEDOUT) return false; // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); return true; } template bool try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { // DR 887 - Sync unknown clock to known clock. const typename _Clock::time_point __c_entry = _Clock::now(); const __clock_t::time_point __s_entry = __clock_t::now(); const auto __delta = __abs_time - __c_entry; const auto __s_atime = __s_entry + __delta; return try_lock_shared_until(__s_atime); } #else // ! (_GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK) // Exclusive ownership template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { unique_lock __lk(_M_mut); if (!_M_gate1.wait_until(__lk, __abs_time, [=]{ return !_M_write_entered(); })) { return false; } _M_state |= _S_write_entered; if (!_M_gate2.wait_until(__lk, __abs_time, [=]{ return _M_readers() == 0; })) { _M_state ^= _S_write_entered; // Wake all threads blocked while the write-entered flag was set. _M_gate1.notify_all(); return false; } return true; } // Shared ownership template bool try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { unique_lock __lk(_M_mut); if (!_M_gate1.wait_until(__lk, __abs_time, [=]{ return _M_state < _S_max_readers; })) { return false; } ++_M_state; return true; } #endif // _GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK }; #endif // _GLIBCXX_HAS_GTHREADS /// shared_lock template class shared_lock { public: typedef _Mutex mutex_type; // Shared locking shared_lock() noexcept : _M_pm(nullptr), _M_owns(false) { } explicit shared_lock(mutex_type& __m) : _M_pm(std::__addressof(__m)), _M_owns(true) { __m.lock_shared(); } shared_lock(mutex_type& __m, defer_lock_t) noexcept : _M_pm(std::__addressof(__m)), _M_owns(false) { } shared_lock(mutex_type& __m, try_to_lock_t) : _M_pm(std::__addressof(__m)), _M_owns(__m.try_lock_shared()) { } shared_lock(mutex_type& __m, adopt_lock_t) : _M_pm(std::__addressof(__m)), _M_owns(true) { } template shared_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __abs_time) : _M_pm(std::__addressof(__m)), _M_owns(__m.try_lock_shared_until(__abs_time)) { } template shared_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __rel_time) : _M_pm(std::__addressof(__m)), _M_owns(__m.try_lock_shared_for(__rel_time)) { } ~shared_lock() { if (_M_owns) _M_pm->unlock_shared(); } shared_lock(shared_lock const&) = delete; shared_lock& operator=(shared_lock const&) = delete; shared_lock(shared_lock&& __sl) noexcept : shared_lock() { swap(__sl); } shared_lock& operator=(shared_lock&& __sl) noexcept { shared_lock(std::move(__sl)).swap(*this); return *this; } void lock() { _M_lockable(); _M_pm->lock_shared(); _M_owns = true; } bool try_lock() { _M_lockable(); return _M_owns = _M_pm->try_lock_shared(); } template bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time) { _M_lockable(); return _M_owns = _M_pm->try_lock_shared_for(__rel_time); } template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { _M_lockable(); return _M_owns = _M_pm->try_lock_shared_until(__abs_time); } void unlock() { if (!_M_owns) __throw_system_error(int(errc::resource_deadlock_would_occur)); _M_pm->unlock_shared(); _M_owns = false; } // Setters void swap(shared_lock& __u) noexcept { std::swap(_M_pm, __u._M_pm); std::swap(_M_owns, __u._M_owns); } mutex_type* release() noexcept { _M_owns = false; return std::exchange(_M_pm, nullptr); } // Getters bool owns_lock() const noexcept { return _M_owns; } explicit operator bool() const noexcept { return _M_owns; } mutex_type* mutex() const noexcept { return _M_pm; } private: void _M_lockable() const { if (_M_pm == nullptr) __throw_system_error(int(errc::operation_not_permitted)); if (_M_owns) __throw_system_error(int(errc::resource_deadlock_would_occur)); } mutex_type* _M_pm; bool _M_owns; }; /// Swap specialization for shared_lock template void swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) noexcept { __x.swap(__y); } #endif // _GLIBCXX_USE_C99_STDINT_TR1 // @} group mutexes _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++14 #endif // _GLIBCXX_SHARED_MUTEX 8/algorithm000064400000004726152526447510006650 0ustar00// -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file include/algorithm * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_ALGORITHM #define _GLIBCXX_ALGORITHM 1 #pragma GCC system_header #include // UK-300. #include #include #ifdef _GLIBCXX_PARALLEL # include #endif #endif /* _GLIBCXX_ALGORITHM */ 8/cwchar000064400000014555152526447510006132 0ustar00// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/cwchar * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c wchar.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 21.4 // #pragma GCC system_header #include #if _GLIBCXX_HAVE_WCHAR_H #include #endif #ifndef _GLIBCXX_CWCHAR #define _GLIBCXX_CWCHAR 1 // Need to do a bit of trickery here with mbstate_t as char_traits // assumes it is in wchar.h, regardless of wchar_t specializations. #ifndef _GLIBCXX_HAVE_MBSTATE_T extern "C" { typedef struct { int __fill[6]; } mbstate_t; } #endif namespace std { using ::mbstate_t; } // namespace std // Get rid of those macros defined in in lieu of real functions. #undef btowc #undef fgetwc #undef fgetws #undef fputwc #undef fputws #undef fwide #undef fwprintf #undef fwscanf #undef getwc #undef getwchar #undef mbrlen #undef mbrtowc #undef mbsinit #undef mbsrtowcs #undef putwc #undef putwchar #undef swprintf #undef swscanf #undef ungetwc #undef vfwprintf #if _GLIBCXX_HAVE_VFWSCANF # undef vfwscanf #endif #undef vswprintf #if _GLIBCXX_HAVE_VSWSCANF # undef vswscanf #endif #undef vwprintf #if _GLIBCXX_HAVE_VWSCANF # undef vwscanf #endif #undef wcrtomb #undef wcscat #undef wcschr #undef wcscmp #undef wcscoll #undef wcscpy #undef wcscspn #undef wcsftime #undef wcslen #undef wcsncat #undef wcsncmp #undef wcsncpy #undef wcspbrk #undef wcsrchr #undef wcsrtombs #undef wcsspn #undef wcsstr #undef wcstod #if _GLIBCXX_HAVE_WCSTOF # undef wcstof #endif #undef wcstok #undef wcstol #undef wcstoul #undef wcsxfrm #undef wctob #undef wmemchr #undef wmemcmp #undef wmemcpy #undef wmemmove #undef wmemset #undef wprintf #undef wscanf #if _GLIBCXX_USE_WCHAR_T namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::wint_t; using ::btowc; using ::fgetwc; using ::fgetws; using ::fputwc; using ::fputws; using ::fwide; using ::fwprintf; using ::fwscanf; using ::getwc; using ::getwchar; using ::mbrlen; using ::mbrtowc; using ::mbsinit; using ::mbsrtowcs; using ::putwc; using ::putwchar; #ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF using ::swprintf; #endif using ::swscanf; using ::ungetwc; using ::vfwprintf; #if _GLIBCXX_HAVE_VFWSCANF using ::vfwscanf; #endif #ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF using ::vswprintf; #endif #if _GLIBCXX_HAVE_VSWSCANF using ::vswscanf; #endif using ::vwprintf; #if _GLIBCXX_HAVE_VWSCANF using ::vwscanf; #endif using ::wcrtomb; using ::wcscat; using ::wcscmp; using ::wcscoll; using ::wcscpy; using ::wcscspn; using ::wcsftime; using ::wcslen; using ::wcsncat; using ::wcsncmp; using ::wcsncpy; using ::wcsrtombs; using ::wcsspn; using ::wcstod; #if _GLIBCXX_HAVE_WCSTOF using ::wcstof; #endif using ::wcstok; using ::wcstol; using ::wcstoul; using ::wcsxfrm; using ::wctob; using ::wmemcmp; using ::wmemcpy; using ::wmemmove; using ::wmemset; using ::wprintf; using ::wscanf; using ::wcschr; using ::wcspbrk; using ::wcsrchr; using ::wcsstr; using ::wmemchr; #ifndef __CORRECT_ISO_CPP_WCHAR_H_PROTO inline wchar_t* wcschr(wchar_t* __p, wchar_t __c) { return wcschr(const_cast(__p), __c); } inline wchar_t* wcspbrk(wchar_t* __s1, const wchar_t* __s2) { return wcspbrk(const_cast(__s1), __s2); } inline wchar_t* wcsrchr(wchar_t* __p, wchar_t __c) { return wcsrchr(const_cast(__p), __c); } inline wchar_t* wcsstr(wchar_t* __s1, const wchar_t* __s2) { return wcsstr(const_cast(__s1), __s2); } inline wchar_t* wmemchr(wchar_t* __p, wchar_t __c, size_t __n) { return wmemchr(const_cast(__p), __c, __n); } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if _GLIBCXX_USE_C99_WCHAR #undef wcstold #undef wcstoll #undef wcstoull namespace __gnu_cxx { #if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC extern "C" long double (wcstold)(const wchar_t * __restrict, wchar_t ** __restrict) throw (); #endif #if !_GLIBCXX_USE_C99_DYNAMIC using ::wcstold; #endif #if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC extern "C" long long int (wcstoll)(const wchar_t * __restrict, wchar_t ** __restrict, int) throw (); extern "C" unsigned long long int (wcstoull)(const wchar_t * __restrict, wchar_t ** __restrict, int) throw (); #endif #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::wcstoll; using ::wcstoull; #endif } // namespace __gnu_cxx namespace std { using ::__gnu_cxx::wcstold; using ::__gnu_cxx::wcstoll; using ::__gnu_cxx::wcstoull; } // namespace #endif #endif //_GLIBCXX_USE_WCHAR_T #if __cplusplus >= 201103L #ifdef _GLIBCXX_USE_WCHAR_T namespace std { #if _GLIBCXX_HAVE_WCSTOF using std::wcstof; #endif #if _GLIBCXX_HAVE_VFWSCANF using std::vfwscanf; #endif #if _GLIBCXX_HAVE_VSWSCANF using std::vswscanf; #endif #if _GLIBCXX_HAVE_VWSCANF using std::vwscanf; #endif #if _GLIBCXX_USE_C99_WCHAR using std::wcstold; using std::wcstoll; using std::wcstoull; #endif } // namespace #endif // _GLIBCXX_USE_WCHAR_T #endif // C++11 #endif 8/codecvt000064400000012335152526447510006304 0ustar00// -*- C++ -*- // Copyright (C) 2015-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // ISO C++ 14882: 22.5 Standard code conversion facets /** @file include/codecvt * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_CODECVT #define _GLIBCXX_CODECVT 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION enum codecvt_mode { consume_header = 4, generate_header = 2, little_endian = 1 }; template class codecvt_utf8 : public codecvt<_Elem, char, mbstate_t> { public: explicit codecvt_utf8(size_t __refs = 0); ~codecvt_utf8(); }; template class codecvt_utf16 : public codecvt<_Elem, char, mbstate_t> { public: explicit codecvt_utf16(size_t __refs = 0); ~codecvt_utf16(); }; template class codecvt_utf8_utf16 : public codecvt<_Elem, char, mbstate_t> { public: explicit codecvt_utf8_utf16(size_t __refs = 0); ~codecvt_utf8_utf16(); }; #define _GLIBCXX_CODECVT_SPECIALIZATION2(_NAME, _ELEM) \ template<> \ class _NAME<_ELEM> \ : public codecvt<_ELEM, char, mbstate_t> \ { \ public: \ typedef _ELEM intern_type; \ typedef char extern_type; \ typedef mbstate_t state_type; \ \ protected: \ _NAME(unsigned long __maxcode, codecvt_mode __mode, size_t __refs) \ : codecvt(__refs), _M_maxcode(__maxcode), _M_mode(__mode) { } \ \ virtual \ ~_NAME(); \ \ virtual result \ do_out(state_type& __state, const intern_type* __from, \ const intern_type* __from_end, const intern_type*& __from_next, \ extern_type* __to, extern_type* __to_end, \ extern_type*& __to_next) const; \ \ virtual result \ do_unshift(state_type& __state, \ extern_type* __to, extern_type* __to_end, \ extern_type*& __to_next) const; \ \ virtual result \ do_in(state_type& __state, \ const extern_type* __from, const extern_type* __from_end, \ const extern_type*& __from_next, \ intern_type* __to, intern_type* __to_end, \ intern_type*& __to_next) const; \ \ virtual \ int do_encoding() const throw(); \ \ virtual \ bool do_always_noconv() const throw(); \ \ virtual \ int do_length(state_type&, const extern_type* __from, \ const extern_type* __end, size_t __max) const; \ \ virtual int \ do_max_length() const throw(); \ \ private: \ unsigned long _M_maxcode; \ codecvt_mode _M_mode; \ } #define _GLIBCXX_CODECVT_SPECIALIZATION(_NAME, _ELEM) \ _GLIBCXX_CODECVT_SPECIALIZATION2(__ ## _NAME ## _base, _ELEM); \ template \ class _NAME<_ELEM, _Maxcode, _Mode> \ : public __ ## _NAME ## _base<_ELEM> \ { \ public: \ explicit \ _NAME(size_t __refs = 0) \ : __ ## _NAME ## _base<_ELEM>(std::min(_Maxcode, 0x10fffful), \ _Mode, __refs) \ { } \ } template class __codecvt_utf8_base; template class __codecvt_utf16_base; template class __codecvt_utf8_utf16_base; _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8, char16_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf16, char16_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8_utf16, char16_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8, char32_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf16, char32_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8_utf16, char32_t); #ifdef _GLIBCXX_USE_WCHAR_T _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8, wchar_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf16, wchar_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8_utf16, wchar_t); #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif #endif /* _GLIBCXX_CODECVT */ 8/sstream000064400000064367152526447510006347 0ustar00// String based streams -*- C++ -*- // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/sstream * This is a Standard C++ Library header. */ // // ISO C++ 14882: 27.7 String-based streams // #ifndef _GLIBCXX_SSTREAM #define _GLIBCXX_SSTREAM 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CXX11 // [27.7.1] template class basic_stringbuf /** * @brief The actual work of input and output (for std::string). * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. * * This class associates either or both of its input and output sequences * with a sequence of characters, which can be initialized from, or made * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) * * For this class, open modes (of type @c ios_base::openmode) have * @c in set if the input sequence can be read, and @c out set if the * output sequence can be written. */ template class basic_stringbuf : public basic_streambuf<_CharT, _Traits> { struct __xfer_bufptrs; public: // Types: typedef _CharT char_type; typedef _Traits traits_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 251. basic_stringbuf missing allocator_type typedef _Alloc allocator_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; typedef basic_streambuf __streambuf_type; typedef basic_string __string_type; typedef typename __string_type::size_type __size_type; protected: /// Place to stash in || out || in | out settings for current stringbuf. ios_base::openmode _M_mode; // Data Members: __string_type _M_string; public: // Constructors: /** * @brief Starts with an empty string buffer. * @param __mode Whether the buffer can read, or write, or both. * * The default constructor initializes the parent class using its * own default ctor. */ explicit basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) : __streambuf_type(), _M_mode(__mode), _M_string() { } /** * @brief Starts with an existing string buffer. * @param __str A string to copy as a starting buffer. * @param __mode Whether the buffer can read, or write, or both. * * This constructor initializes the parent class using its * own default ctor. */ explicit basic_stringbuf(const __string_type& __str, ios_base::openmode __mode = ios_base::in | ios_base::out) : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size(), __str.get_allocator()) { _M_stringbuf_init(__mode); } #if __cplusplus >= 201103L basic_stringbuf(const basic_stringbuf&) = delete; basic_stringbuf(basic_stringbuf&& __rhs) : basic_stringbuf(std::move(__rhs), __xfer_bufptrs(__rhs, this)) { __rhs._M_sync(const_cast(__rhs._M_string.data()), 0, 0); } // 27.8.2.2 Assign and swap: basic_stringbuf& operator=(const basic_stringbuf&) = delete; basic_stringbuf& operator=(basic_stringbuf&& __rhs) { __xfer_bufptrs __st{__rhs, this}; const __streambuf_type& __base = __rhs; __streambuf_type::operator=(__base); this->pubimbue(__rhs.getloc()); _M_mode = __rhs._M_mode; _M_string = std::move(__rhs._M_string); __rhs._M_sync(const_cast(__rhs._M_string.data()), 0, 0); return *this; } void swap(basic_stringbuf& __rhs) { __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)}; __xfer_bufptrs __r_st{__rhs, this}; __streambuf_type& __base = __rhs; __streambuf_type::swap(__base); __rhs.pubimbue(this->pubimbue(__rhs.getloc())); std::swap(_M_mode, __rhs._M_mode); std::swap(_M_string, __rhs._M_string); } #endif // Get and set: /** * @brief Copying out the string buffer. * @return A copy of one of the underlying sequences. * * If the buffer is only created in input mode, the underlying * character sequence is equal to the input sequence; otherwise, it * is equal to the output sequence. [27.7.1.2]/1 */ __string_type str() const { __string_type __ret(_M_string.get_allocator()); if (this->pptr()) { // The current egptr() may not be the actual string end. if (this->pptr() > this->egptr()) __ret.assign(this->pbase(), this->pptr()); else __ret.assign(this->pbase(), this->egptr()); } else __ret = _M_string; return __ret; } /** * @brief Setting a new buffer. * @param __s The string to use as a new sequence. * * Deallocates any previous stored sequence, then copies @a s to * use as a new one. */ void str(const __string_type& __s) { // Cannot use _M_string = __s, since v3 strings are COW // (not always true now but assign() always works). _M_string.assign(__s.data(), __s.size()); _M_stringbuf_init(_M_mode); } protected: // Common initialization code goes here. void _M_stringbuf_init(ios_base::openmode __mode) { _M_mode = __mode; __size_type __len = 0; if (_M_mode & (ios_base::ate | ios_base::app)) __len = _M_string.size(); _M_sync(const_cast(_M_string.data()), 0, __len); } virtual streamsize showmanyc() { streamsize __ret = -1; if (_M_mode & ios_base::in) { _M_update_egptr(); __ret = this->egptr() - this->gptr(); } return __ret; } virtual int_type underflow(); virtual int_type pbackfail(int_type __c = traits_type::eof()); virtual int_type overflow(int_type __c = traits_type::eof()); /** * @brief Manipulates the buffer. * @param __s Pointer to a buffer area. * @param __n Size of @a __s. * @return @c this * * If no buffer has already been created, and both @a __s and @a __n are * non-zero, then @c __s is used as a buffer; see * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering * for more. */ virtual __streambuf_type* setbuf(char_type* __s, streamsize __n) { if (__s && __n >= 0) { // This is implementation-defined behavior, and assumes // that an external char_type array of length __n exists // and has been pre-allocated. If this is not the case, // things will quickly blow up. // Step 1: Destroy the current internal array. _M_string.clear(); // Step 2: Use the external array. _M_sync(__s, __n, 0); } return this; } virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode = ios_base::in | ios_base::out); virtual pos_type seekpos(pos_type __sp, ios_base::openmode __mode = ios_base::in | ios_base::out); // Internal function for correctly updating the internal buffer // for a particular _M_string, due to initialization or re-sizing // of an existing _M_string. void _M_sync(char_type* __base, __size_type __i, __size_type __o); // Internal function for correctly updating egptr() to the actual // string end. void _M_update_egptr() { const bool __testin = _M_mode & ios_base::in; if (this->pptr() && this->pptr() > this->egptr()) { if (__testin) this->setg(this->eback(), this->gptr(), this->pptr()); else this->setg(this->pptr(), this->pptr(), this->pptr()); } } // Works around the issue with pbump, part of the protected // interface of basic_streambuf, taking just an int. void _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off); private: #if __cplusplus >= 201103L #if _GLIBCXX_USE_CXX11_ABI // This type captures the state of the gptr / pptr pointers as offsets // so they can be restored in another object after moving the string. struct __xfer_bufptrs { __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to) : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1} { const _CharT* const __str = __from._M_string.data(); const _CharT* __end = nullptr; if (__from.eback()) { _M_goff[0] = __from.eback() - __str; _M_goff[1] = __from.gptr() - __str; _M_goff[2] = __from.egptr() - __str; __end = __from.egptr(); } if (__from.pbase()) { _M_poff[0] = __from.pbase() - __str; _M_poff[1] = __from.pptr() - __from.pbase(); _M_poff[2] = __from.epptr() - __str; if (__from.pptr() > __end) __end = __from.pptr(); } // Set _M_string length to the greater of the get and put areas. if (__end) { // The const_cast avoids changing this constructor's signature, // because it is exported from the dynamic library. auto& __mut_from = const_cast(__from); __mut_from._M_string._M_length(__end - __str); } } ~__xfer_bufptrs() { char_type* __str = const_cast(_M_to->_M_string.data()); if (_M_goff[0] != -1) _M_to->setg(__str+_M_goff[0], __str+_M_goff[1], __str+_M_goff[2]); if (_M_poff[0] != -1) _M_to->_M_pbump(__str+_M_poff[0], __str+_M_poff[2], _M_poff[1]); } basic_stringbuf* _M_to; off_type _M_goff[3]; off_type _M_poff[3]; }; #else // This type does nothing when using Copy-On-Write strings. struct __xfer_bufptrs { __xfer_bufptrs(const basic_stringbuf&, basic_stringbuf*) { } }; #endif // The move constructor initializes an __xfer_bufptrs temporary then // delegates to this constructor to performs moves during its lifetime. basic_stringbuf(basic_stringbuf&& __rhs, __xfer_bufptrs&&) : __streambuf_type(static_cast(__rhs)), _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string)) { } #endif }; // [27.7.2] Template class basic_istringstream /** * @brief Controlling input for std::string. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. * * This class supports reading from objects of type std::basic_string, * using the inherited functions from std::basic_istream. To control * the associated sequence, an instance of std::basic_stringbuf is used, * which this page refers to as @c sb. */ template class basic_istringstream : public basic_istream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 251. basic_stringbuf missing allocator_type typedef _Alloc allocator_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; typedef basic_istream __istream_type; private: __stringbuf_type _M_stringbuf; public: // Constructors: /** * @brief Default constructor starts with an empty string buffer. * @param __mode Whether the buffer can read, or write, or both. * * @c ios_base::in is automatically included in @a __mode. * * Initializes @c sb using @c __mode|in, and passes @c &sb to the base * class initializer. Does not allocate any buffer. * * That's a lie. We initialize the base class with NULL, because the * string class does its own memory management. */ explicit basic_istringstream(ios_base::openmode __mode = ios_base::in) : __istream_type(), _M_stringbuf(__mode | ios_base::in) { this->init(&_M_stringbuf); } /** * @brief Starts with an existing string buffer. * @param __str A string to copy as a starting buffer. * @param __mode Whether the buffer can read, or write, or both. * * @c ios_base::in is automatically included in @a mode. * * Initializes @c sb using @a str and @c mode|in, and passes @c &sb * to the base class initializer. * * That's a lie. We initialize the base class with NULL, because the * string class does its own memory management. */ explicit basic_istringstream(const __string_type& __str, ios_base::openmode __mode = ios_base::in) : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) { this->init(&_M_stringbuf); } /** * @brief The destructor does nothing. * * The buffer is deallocated by the stringbuf object, not the * formatting stream. */ ~basic_istringstream() { } #if __cplusplus >= 201103L basic_istringstream(const basic_istringstream&) = delete; basic_istringstream(basic_istringstream&& __rhs) : __istream_type(std::move(__rhs)), _M_stringbuf(std::move(__rhs._M_stringbuf)) { __istream_type::set_rdbuf(&_M_stringbuf); } // 27.8.3.2 Assign and swap: basic_istringstream& operator=(const basic_istringstream&) = delete; basic_istringstream& operator=(basic_istringstream&& __rhs) { __istream_type::operator=(std::move(__rhs)); _M_stringbuf = std::move(__rhs._M_stringbuf); return *this; } void swap(basic_istringstream& __rhs) { __istream_type::swap(__rhs); _M_stringbuf.swap(__rhs._M_stringbuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_stringbuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __stringbuf_type* rdbuf() const { return const_cast<__stringbuf_type*>(&_M_stringbuf); } /** * @brief Copying out the string buffer. * @return @c rdbuf()->str() */ __string_type str() const { return _M_stringbuf.str(); } /** * @brief Setting a new buffer. * @param __s The string to use as a new sequence. * * Calls @c rdbuf()->str(s). */ void str(const __string_type& __s) { _M_stringbuf.str(__s); } }; // [27.7.3] Template class basic_ostringstream /** * @brief Controlling output for std::string. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. * * This class supports writing to objects of type std::basic_string, * using the inherited functions from std::basic_ostream. To control * the associated sequence, an instance of std::basic_stringbuf is used, * which this page refers to as @c sb. */ template class basic_ostringstream : public basic_ostream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 251. basic_stringbuf missing allocator_type typedef _Alloc allocator_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; typedef basic_ostream __ostream_type; private: __stringbuf_type _M_stringbuf; public: // Constructors/destructor: /** * @brief Default constructor starts with an empty string buffer. * @param __mode Whether the buffer can read, or write, or both. * * @c ios_base::out is automatically included in @a mode. * * Initializes @c sb using @c mode|out, and passes @c &sb to the base * class initializer. Does not allocate any buffer. * * That's a lie. We initialize the base class with NULL, because the * string class does its own memory management. */ explicit basic_ostringstream(ios_base::openmode __mode = ios_base::out) : __ostream_type(), _M_stringbuf(__mode | ios_base::out) { this->init(&_M_stringbuf); } /** * @brief Starts with an existing string buffer. * @param __str A string to copy as a starting buffer. * @param __mode Whether the buffer can read, or write, or both. * * @c ios_base::out is automatically included in @a mode. * * Initializes @c sb using @a str and @c mode|out, and passes @c &sb * to the base class initializer. * * That's a lie. We initialize the base class with NULL, because the * string class does its own memory management. */ explicit basic_ostringstream(const __string_type& __str, ios_base::openmode __mode = ios_base::out) : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) { this->init(&_M_stringbuf); } /** * @brief The destructor does nothing. * * The buffer is deallocated by the stringbuf object, not the * formatting stream. */ ~basic_ostringstream() { } #if __cplusplus >= 201103L basic_ostringstream(const basic_ostringstream&) = delete; basic_ostringstream(basic_ostringstream&& __rhs) : __ostream_type(std::move(__rhs)), _M_stringbuf(std::move(__rhs._M_stringbuf)) { __ostream_type::set_rdbuf(&_M_stringbuf); } // 27.8.3.2 Assign and swap: basic_ostringstream& operator=(const basic_ostringstream&) = delete; basic_ostringstream& operator=(basic_ostringstream&& __rhs) { __ostream_type::operator=(std::move(__rhs)); _M_stringbuf = std::move(__rhs._M_stringbuf); return *this; } void swap(basic_ostringstream& __rhs) { __ostream_type::swap(__rhs); _M_stringbuf.swap(__rhs._M_stringbuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_stringbuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __stringbuf_type* rdbuf() const { return const_cast<__stringbuf_type*>(&_M_stringbuf); } /** * @brief Copying out the string buffer. * @return @c rdbuf()->str() */ __string_type str() const { return _M_stringbuf.str(); } /** * @brief Setting a new buffer. * @param __s The string to use as a new sequence. * * Calls @c rdbuf()->str(s). */ void str(const __string_type& __s) { _M_stringbuf.str(__s); } }; // [27.7.4] Template class basic_stringstream /** * @brief Controlling input and output for std::string. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. * * This class supports reading from and writing to objects of type * std::basic_string, using the inherited functions from * std::basic_iostream. To control the associated sequence, an instance * of std::basic_stringbuf is used, which this page refers to as @c sb. */ template class basic_stringstream : public basic_iostream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 251. basic_stringbuf missing allocator_type typedef _Alloc allocator_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard Types: typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; typedef basic_iostream __iostream_type; private: __stringbuf_type _M_stringbuf; public: // Constructors/destructors /** * @brief Default constructor starts with an empty string buffer. * @param __m Whether the buffer can read, or write, or both. * * Initializes @c sb using the mode from @c __m, and passes @c * &sb to the base class initializer. Does not allocate any * buffer. * * That's a lie. We initialize the base class with NULL, because the * string class does its own memory management. */ explicit basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) : __iostream_type(), _M_stringbuf(__m) { this->init(&_M_stringbuf); } /** * @brief Starts with an existing string buffer. * @param __str A string to copy as a starting buffer. * @param __m Whether the buffer can read, or write, or both. * * Initializes @c sb using @a __str and @c __m, and passes @c &sb * to the base class initializer. * * That's a lie. We initialize the base class with NULL, because the * string class does its own memory management. */ explicit basic_stringstream(const __string_type& __str, ios_base::openmode __m = ios_base::out | ios_base::in) : __iostream_type(), _M_stringbuf(__str, __m) { this->init(&_M_stringbuf); } /** * @brief The destructor does nothing. * * The buffer is deallocated by the stringbuf object, not the * formatting stream. */ ~basic_stringstream() { } #if __cplusplus >= 201103L basic_stringstream(const basic_stringstream&) = delete; basic_stringstream(basic_stringstream&& __rhs) : __iostream_type(std::move(__rhs)), _M_stringbuf(std::move(__rhs._M_stringbuf)) { __iostream_type::set_rdbuf(&_M_stringbuf); } // 27.8.3.2 Assign and swap: basic_stringstream& operator=(const basic_stringstream&) = delete; basic_stringstream& operator=(basic_stringstream&& __rhs) { __iostream_type::operator=(std::move(__rhs)); _M_stringbuf = std::move(__rhs._M_stringbuf); return *this; } void swap(basic_stringstream& __rhs) { __iostream_type::swap(__rhs); _M_stringbuf.swap(__rhs._M_stringbuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_stringbuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __stringbuf_type* rdbuf() const { return const_cast<__stringbuf_type*>(&_M_stringbuf); } /** * @brief Copying out the string buffer. * @return @c rdbuf()->str() */ __string_type str() const { return _M_stringbuf.str(); } /** * @brief Setting a new buffer. * @param __s The string to use as a new sequence. * * Calls @c rdbuf()->str(s). */ void str(const __string_type& __s) { _M_stringbuf.str(__s); } }; #if __cplusplus >= 201103L /// Swap specialization for stringbufs. template inline void swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x, basic_stringbuf<_CharT, _Traits, _Allocator>& __y) { __x.swap(__y); } /// Swap specialization for istringstreams. template inline void swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x, basic_istringstream<_CharT, _Traits, _Allocator>& __y) { __x.swap(__y); } /// Swap specialization for ostringstreams. template inline void swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x, basic_ostringstream<_CharT, _Traits, _Allocator>& __y) { __x.swap(__y); } /// Swap specialization for stringstreams. template inline void swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x, basic_stringstream<_CharT, _Traits, _Allocator>& __y) { __x.swap(__y); } #endif _GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include #endif /* _GLIBCXX_SSTREAM */ 8/decimal/decimal000064400000042344152526447520007655 0ustar00// -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file decimal/decimal * This is a Standard C++ Library header. */ // ISO/IEC TR 24733 // Written by Janis Johnson #ifndef _GLIBCXX_DECIMAL #define _GLIBCXX_DECIMAL 1 #pragma GCC system_header #include #ifndef _GLIBCXX_USE_DECIMAL_FLOAT #error This file requires compiler and library support for ISO/IEC TR 24733 \ that is currently not available. #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup decimal Decimal Floating-Point Arithmetic * @ingroup numerics * * Classes and functions for decimal floating-point arithmetic. * @{ */ /** @namespace std::decimal * @brief ISO/IEC TR 24733 Decimal floating-point arithmetic. */ namespace decimal { class decimal32; class decimal64; class decimal128; // 3.2.5 Initialization from coefficient and exponent. static decimal32 make_decimal32(long long __coeff, int __exp); static decimal32 make_decimal32(unsigned long long __coeff, int __exp); static decimal64 make_decimal64(long long __coeff, int __exp); static decimal64 make_decimal64(unsigned long long __coeff, int __exp); static decimal128 make_decimal128(long long __coeff, int __exp); static decimal128 make_decimal128(unsigned long long __coeff, int __exp); /// Non-conforming extension: Conversion to integral type. long long decimal32_to_long_long(decimal32 __d); long long decimal64_to_long_long(decimal64 __d); long long decimal128_to_long_long(decimal128 __d); long long decimal_to_long_long(decimal32 __d); long long decimal_to_long_long(decimal64 __d); long long decimal_to_long_long(decimal128 __d); // 3.2.6 Conversion to generic floating-point type. float decimal32_to_float(decimal32 __d); float decimal64_to_float(decimal64 __d); float decimal128_to_float(decimal128 __d); float decimal_to_float(decimal32 __d); float decimal_to_float(decimal64 __d); float decimal_to_float(decimal128 __d); double decimal32_to_double(decimal32 __d); double decimal64_to_double(decimal64 __d); double decimal128_to_double(decimal128 __d); double decimal_to_double(decimal32 __d); double decimal_to_double(decimal64 __d); double decimal_to_double(decimal128 __d); long double decimal32_to_long_double(decimal32 __d); long double decimal64_to_long_double(decimal64 __d); long double decimal128_to_long_double(decimal128 __d); long double decimal_to_long_double(decimal32 __d); long double decimal_to_long_double(decimal64 __d); long double decimal_to_long_double(decimal128 __d); // 3.2.7 Unary arithmetic operators. decimal32 operator+(decimal32 __rhs); decimal64 operator+(decimal64 __rhs); decimal128 operator+(decimal128 __rhs); decimal32 operator-(decimal32 __rhs); decimal64 operator-(decimal64 __rhs); decimal128 operator-(decimal128 __rhs); // 3.2.8 Binary arithmetic operators. #define _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(_Op, _T1, _T2, _T3) \ _T1 operator _Op(_T2 __lhs, _T3 __rhs); #define _DECLARE_DECIMAL_BINARY_OP_WITH_INT(_Op, _Tp) \ _Tp operator _Op(_Tp __lhs, int __rhs); \ _Tp operator _Op(_Tp __lhs, unsigned int __rhs); \ _Tp operator _Op(_Tp __lhs, long __rhs); \ _Tp operator _Op(_Tp __lhs, unsigned long __rhs); \ _Tp operator _Op(_Tp __lhs, long long __rhs); \ _Tp operator _Op(_Tp __lhs, unsigned long long __rhs); \ _Tp operator _Op(int __lhs, _Tp __rhs); \ _Tp operator _Op(unsigned int __lhs, _Tp __rhs); \ _Tp operator _Op(long __lhs, _Tp __rhs); \ _Tp operator _Op(unsigned long __lhs, _Tp __rhs); \ _Tp operator _Op(long long __lhs, _Tp __rhs); \ _Tp operator _Op(unsigned long long __lhs, _Tp __rhs); _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal32, decimal32, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(+, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal32, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal64, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal64, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(+, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal32, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal64, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(+, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal32, decimal32, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(-, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal32, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal64, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal64, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(-, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal32, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal64, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(-, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal32, decimal32, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(*, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal32, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal64, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal64, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(*, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal32, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal64, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(*, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal32, decimal32, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(/, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal32, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal64, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal64, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(/, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal32, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal64, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal32) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal64) _DECLARE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal128) _DECLARE_DECIMAL_BINARY_OP_WITH_INT(/, decimal128) #undef _DECLARE_DECIMAL_BINARY_OP_WITH_DEC #undef _DECLARE_DECIMAL_BINARY_OP_WITH_INT // 3.2.9 Comparison operators. #define _DECLARE_DECIMAL_COMPARISON(_Op, _Tp) \ bool operator _Op(_Tp __lhs, decimal32 __rhs); \ bool operator _Op(_Tp __lhs, decimal64 __rhs); \ bool operator _Op(_Tp __lhs, decimal128 __rhs); \ bool operator _Op(_Tp __lhs, int __rhs); \ bool operator _Op(_Tp __lhs, unsigned int __rhs); \ bool operator _Op(_Tp __lhs, long __rhs); \ bool operator _Op(_Tp __lhs, unsigned long __rhs); \ bool operator _Op(_Tp __lhs, long long __rhs); \ bool operator _Op(_Tp __lhs, unsigned long long __rhs); \ bool operator _Op(int __lhs, _Tp __rhs); \ bool operator _Op(unsigned int __lhs, _Tp __rhs); \ bool operator _Op(long __lhs, _Tp __rhs); \ bool operator _Op(unsigned long __lhs, _Tp __rhs); \ bool operator _Op(long long __lhs, _Tp __rhs); \ bool operator _Op(unsigned long long __lhs, _Tp __rhs); _DECLARE_DECIMAL_COMPARISON(==, decimal32) _DECLARE_DECIMAL_COMPARISON(==, decimal64) _DECLARE_DECIMAL_COMPARISON(==, decimal128) _DECLARE_DECIMAL_COMPARISON(!=, decimal32) _DECLARE_DECIMAL_COMPARISON(!=, decimal64) _DECLARE_DECIMAL_COMPARISON(!=, decimal128) _DECLARE_DECIMAL_COMPARISON(<, decimal32) _DECLARE_DECIMAL_COMPARISON(<, decimal64) _DECLARE_DECIMAL_COMPARISON(<, decimal128) _DECLARE_DECIMAL_COMPARISON(>=, decimal32) _DECLARE_DECIMAL_COMPARISON(>=, decimal64) _DECLARE_DECIMAL_COMPARISON(>=, decimal128) _DECLARE_DECIMAL_COMPARISON(>, decimal32) _DECLARE_DECIMAL_COMPARISON(>, decimal64) _DECLARE_DECIMAL_COMPARISON(>, decimal128) _DECLARE_DECIMAL_COMPARISON(>=, decimal32) _DECLARE_DECIMAL_COMPARISON(>=, decimal64) _DECLARE_DECIMAL_COMPARISON(>=, decimal128) #undef _DECLARE_DECIMAL_COMPARISON /// 3.2.2 Class decimal32. class decimal32 { public: typedef float __decfloat32 __attribute__((mode(SD))); // 3.2.2.2 Construct/copy/destroy. decimal32() : __val(0.e-101DF) {} // 3.2.2.3 Conversion from floating-point type. explicit decimal32(decimal64 __d64); explicit decimal32(decimal128 __d128); explicit decimal32(float __r) : __val(__r) {} explicit decimal32(double __r) : __val(__r) {} explicit decimal32(long double __r) : __val(__r) {} // 3.2.2.4 Conversion from integral type. decimal32(int __z) : __val(__z) {} decimal32(unsigned int __z) : __val(__z) {} decimal32(long __z) : __val(__z) {} decimal32(unsigned long __z) : __val(__z) {} decimal32(long long __z) : __val(__z) {} decimal32(unsigned long long __z) : __val(__z) {} /// Conforming extension: Conversion from scalar decimal type. decimal32(__decfloat32 __z) : __val(__z) {} #if __cplusplus >= 201103L // 3.2.2.5 Conversion to integral type. // Note: explicit per n3407. explicit operator long long() const { return (long long)__val; } #endif // 3.2.2.6 Increment and decrement operators. decimal32& operator++() { __val += 1; return *this; } decimal32 operator++(int) { decimal32 __tmp = *this; __val += 1; return __tmp; } decimal32& operator--() { __val -= 1; return *this; } decimal32 operator--(int) { decimal32 __tmp = *this; __val -= 1; return __tmp; } // 3.2.2.7 Compound assignment. #define _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(_Op) \ decimal32& operator _Op(decimal32 __rhs); \ decimal32& operator _Op(decimal64 __rhs); \ decimal32& operator _Op(decimal128 __rhs); \ decimal32& operator _Op(int __rhs); \ decimal32& operator _Op(unsigned int __rhs); \ decimal32& operator _Op(long __rhs); \ decimal32& operator _Op(unsigned long __rhs); \ decimal32& operator _Op(long long __rhs); \ decimal32& operator _Op(unsigned long long __rhs); _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(+=) _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(-=) _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(*=) _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT(/=) #undef _DECLARE_DECIMAL32_COMPOUND_ASSIGNMENT private: __decfloat32 __val; public: __decfloat32 __getval(void) { return __val; } void __setval(__decfloat32 __x) { __val = __x; } }; /// 3.2.3 Class decimal64. class decimal64 { public: typedef float __decfloat64 __attribute__((mode(DD))); // 3.2.3.2 Construct/copy/destroy. decimal64() : __val(0.e-398dd) {} // 3.2.3.3 Conversion from floating-point type. decimal64(decimal32 d32); explicit decimal64(decimal128 d128); explicit decimal64(float __r) : __val(__r) {} explicit decimal64(double __r) : __val(__r) {} explicit decimal64(long double __r) : __val(__r) {} // 3.2.3.4 Conversion from integral type. decimal64(int __z) : __val(__z) {} decimal64(unsigned int __z) : __val(__z) {} decimal64(long __z) : __val(__z) {} decimal64(unsigned long __z) : __val(__z) {} decimal64(long long __z) : __val(__z) {} decimal64(unsigned long long __z) : __val(__z) {} /// Conforming extension: Conversion from scalar decimal type. decimal64(__decfloat64 __z) : __val(__z) {} #if __cplusplus >= 201103L // 3.2.3.5 Conversion to integral type. // Note: explicit per n3407. explicit operator long long() const { return (long long)__val; } #endif // 3.2.3.6 Increment and decrement operators. decimal64& operator++() { __val += 1; return *this; } decimal64 operator++(int) { decimal64 __tmp = *this; __val += 1; return __tmp; } decimal64& operator--() { __val -= 1; return *this; } decimal64 operator--(int) { decimal64 __tmp = *this; __val -= 1; return __tmp; } // 3.2.3.7 Compound assignment. #define _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(_Op) \ decimal64& operator _Op(decimal32 __rhs); \ decimal64& operator _Op(decimal64 __rhs); \ decimal64& operator _Op(decimal128 __rhs); \ decimal64& operator _Op(int __rhs); \ decimal64& operator _Op(unsigned int __rhs); \ decimal64& operator _Op(long __rhs); \ decimal64& operator _Op(unsigned long __rhs); \ decimal64& operator _Op(long long __rhs); \ decimal64& operator _Op(unsigned long long __rhs); _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(+=) _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(-=) _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(*=) _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT(/=) #undef _DECLARE_DECIMAL64_COMPOUND_ASSIGNMENT private: __decfloat64 __val; public: __decfloat64 __getval(void) { return __val; } void __setval(__decfloat64 __x) { __val = __x; } }; /// 3.2.4 Class decimal128. class decimal128 { public: typedef float __decfloat128 __attribute__((mode(TD))); // 3.2.4.2 Construct/copy/destroy. decimal128() : __val(0.e-6176DL) {} // 3.2.4.3 Conversion from floating-point type. decimal128(decimal32 d32); decimal128(decimal64 d64); explicit decimal128(float __r) : __val(__r) {} explicit decimal128(double __r) : __val(__r) {} explicit decimal128(long double __r) : __val(__r) {} // 3.2.4.4 Conversion from integral type. decimal128(int __z) : __val(__z) {} decimal128(unsigned int __z) : __val(__z) {} decimal128(long __z) : __val(__z) {} decimal128(unsigned long __z) : __val(__z) {} decimal128(long long __z) : __val(__z) {} decimal128(unsigned long long __z) : __val(__z) {} /// Conforming extension: Conversion from scalar decimal type. decimal128(__decfloat128 __z) : __val(__z) {} #if __cplusplus >= 201103L // 3.2.4.5 Conversion to integral type. // Note: explicit per n3407. explicit operator long long() const { return (long long)__val; } #endif // 3.2.4.6 Increment and decrement operators. decimal128& operator++() { __val += 1; return *this; } decimal128 operator++(int) { decimal128 __tmp = *this; __val += 1; return __tmp; } decimal128& operator--() { __val -= 1; return *this; } decimal128 operator--(int) { decimal128 __tmp = *this; __val -= 1; return __tmp; } // 3.2.4.7 Compound assignment. #define _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(_Op) \ decimal128& operator _Op(decimal32 __rhs); \ decimal128& operator _Op(decimal64 __rhs); \ decimal128& operator _Op(decimal128 __rhs); \ decimal128& operator _Op(int __rhs); \ decimal128& operator _Op(unsigned int __rhs); \ decimal128& operator _Op(long __rhs); \ decimal128& operator _Op(unsigned long __rhs); \ decimal128& operator _Op(long long __rhs); \ decimal128& operator _Op(unsigned long long __rhs); _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(+=) _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(-=) _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(*=) _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT(/=) #undef _DECLARE_DECIMAL128_COMPOUND_ASSIGNMENT private: __decfloat128 __val; public: __decfloat128 __getval(void) { return __val; } void __setval(__decfloat128 __x) { __val = __x; } }; #define _GLIBCXX_USE_DECIMAL_ 1 } // namespace decimal // @} group decimal _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #include #endif /* _GLIBCXX_DECIMAL */ 8/decimal/decimal.h000064400000041147152526447520010103 0ustar00// decimal classes -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file decimal/decimal.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{decimal} */ // ISO/IEC TR 24733 // Written by Janis Johnson #ifndef _GLIBCXX_DECIMAL_IMPL #define _GLIBCXX_DECIMAL_IMPL 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace decimal { // ISO/IEC TR 24733 3.2.[234].1 Construct/copy/destroy. inline decimal32::decimal32(decimal64 __r) : __val(__r.__getval()) {} inline decimal32::decimal32(decimal128 __r) : __val(__r.__getval()) {} inline decimal64::decimal64(decimal32 __r) : __val(__r.__getval()) {} inline decimal64::decimal64(decimal128 __r) : __val(__r.__getval()) {} inline decimal128::decimal128(decimal32 __r) : __val(__r.__getval()) {} inline decimal128::decimal128(decimal64 __r) : __val(__r.__getval()) {} // ISO/IEC TR 24733 3.2.[234].6 Compound assignment. #define _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC(_Op1, _Op2, _T1, _T2) \ inline _T1& _T1::operator _Op1(_T2 __rhs) \ { \ __setval(__getval() _Op2 __rhs.__getval()); \ return *this; \ } #define _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, _T2) \ inline _T1& _T1::operator _Op1(_T2 __rhs) \ { \ __setval(__getval() _Op2 __rhs); \ return *this; \ } #define _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(_Op1, _Op2, _T1) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC(_Op1, _Op2, _T1, decimal32) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC(_Op1, _Op2, _T1, decimal64) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC(_Op1, _Op2, _T1, decimal128) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, int) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, unsigned int) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, long) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, unsigned long)\ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, long long) \ _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT(_Op1, _Op2, _T1, unsigned long long) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(+=, +, decimal32) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(-=, -, decimal32) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(*=, *, decimal32) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(/=, /, decimal32) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(+=, +, decimal64) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(-=, -, decimal64) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(*=, *, decimal64) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(/=, /, decimal64) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(+=, +, decimal128) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(-=, -, decimal128) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(*=, *, decimal128) _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS(/=, /, decimal128) #undef _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_DEC #undef _DEFINE_DECIMAL_COMPOUND_ASSIGNMENT_INT #undef _DEFINE_DECIMAL_COMPOUND_ASSIGNMENTS // Extension: Conversion to integral type. inline long long decimal32_to_long_long(decimal32 __d) { return (long long)__d.__getval(); } inline long long decimal64_to_long_long(decimal64 __d) { return (long long)__d.__getval(); } inline long long decimal128_to_long_long(decimal128 __d) { return (long long)__d.__getval(); } inline long long decimal_to_long_long(decimal32 __d) { return (long long)__d.__getval(); } inline long long decimal_to_long_long(decimal64 __d) { return (long long)__d.__getval(); } inline long long decimal_to_long_long(decimal128 __d) { return (long long)__d.__getval(); } // ISO/IEC TR 24733 3.2.5 Initialization from coefficient and exponent. static decimal32 make_decimal32(long long __coeff, int __exponent) { decimal32 __decexp = 1, __multiplier; if (__exponent < 0) { __multiplier = 1.E-1DF; __exponent = -__exponent; } else __multiplier = 1.E1DF; for (int __i = 0; __i < __exponent; ++__i) __decexp *= __multiplier; return __coeff * __decexp; } static decimal32 make_decimal32(unsigned long long __coeff, int __exponent) { decimal32 __decexp = 1, __multiplier; if (__exponent < 0) { __multiplier = 1.E-1DF; __exponent = -__exponent; } else __multiplier = 1.E1DF; for (int __i = 0; __i < __exponent; ++__i) __decexp *= __multiplier; return __coeff * __decexp; } static decimal64 make_decimal64(long long __coeff, int __exponent) { decimal64 __decexp = 1, __multiplier; if (__exponent < 0) { __multiplier = 1.E-1DD; __exponent = -__exponent; } else __multiplier = 1.E1DD; for (int __i = 0; __i < __exponent; ++__i) __decexp *= __multiplier; return __coeff * __decexp; } static decimal64 make_decimal64(unsigned long long __coeff, int __exponent) { decimal64 __decexp = 1, __multiplier; if (__exponent < 0) { __multiplier = 1.E-1DD; __exponent = -__exponent; } else __multiplier = 1.E1DD; for (int __i = 0; __i < __exponent; ++__i) __decexp *= __multiplier; return __coeff * __decexp; } static decimal128 make_decimal128(long long __coeff, int __exponent) { decimal128 __decexp = 1, __multiplier; if (__exponent < 0) { __multiplier = 1.E-1DL; __exponent = -__exponent; } else __multiplier = 1.E1DL; for (int __i = 0; __i < __exponent; ++__i) __decexp *= __multiplier; return __coeff * __decexp; } static decimal128 make_decimal128(unsigned long long __coeff, int __exponent) { decimal128 __decexp = 1, __multiplier; if (__exponent < 0) { __multiplier = 1.E-1DL; __exponent = -__exponent; } else __multiplier = 1.E1DL; for (int __i = 0; __i < __exponent; ++__i) __decexp *= __multiplier; return __coeff * __decexp; } // ISO/IEC TR 24733 3.2.6 Conversion to generic floating-point type. inline float decimal32_to_float(decimal32 __d) { return (float)__d.__getval(); } inline float decimal64_to_float(decimal64 __d) { return (float)__d.__getval(); } inline float decimal128_to_float(decimal128 __d) { return (float)__d.__getval(); } inline float decimal_to_float(decimal32 __d) { return (float)__d.__getval(); } inline float decimal_to_float(decimal64 __d) { return (float)__d.__getval(); } inline float decimal_to_float(decimal128 __d) { return (float)__d.__getval(); } inline double decimal32_to_double(decimal32 __d) { return (double)__d.__getval(); } inline double decimal64_to_double(decimal64 __d) { return (double)__d.__getval(); } inline double decimal128_to_double(decimal128 __d) { return (double)__d.__getval(); } inline double decimal_to_double(decimal32 __d) { return (double)__d.__getval(); } inline double decimal_to_double(decimal64 __d) { return (double)__d.__getval(); } inline double decimal_to_double(decimal128 __d) { return (double)__d.__getval(); } inline long double decimal32_to_long_double(decimal32 __d) { return (long double)__d.__getval(); } inline long double decimal64_to_long_double(decimal64 __d) { return (long double)__d.__getval(); } inline long double decimal128_to_long_double(decimal128 __d) { return (long double)__d.__getval(); } inline long double decimal_to_long_double(decimal32 __d) { return (long double)__d.__getval(); } inline long double decimal_to_long_double(decimal64 __d) { return (long double)__d.__getval(); } inline long double decimal_to_long_double(decimal128 __d) { return (long double)__d.__getval(); } // ISO/IEC TR 24733 3.2.7 Unary arithmetic operators. #define _DEFINE_DECIMAL_UNARY_OP(_Op, _Tp) \ inline _Tp operator _Op(_Tp __rhs) \ { \ _Tp __tmp; \ __tmp.__setval(_Op __rhs.__getval()); \ return __tmp; \ } _DEFINE_DECIMAL_UNARY_OP(+, decimal32) _DEFINE_DECIMAL_UNARY_OP(+, decimal64) _DEFINE_DECIMAL_UNARY_OP(+, decimal128) _DEFINE_DECIMAL_UNARY_OP(-, decimal32) _DEFINE_DECIMAL_UNARY_OP(-, decimal64) _DEFINE_DECIMAL_UNARY_OP(-, decimal128) #undef _DEFINE_DECIMAL_UNARY_OP // ISO/IEC TR 24733 3.2.8 Binary arithmetic operators. #define _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(_Op, _T1, _T2, _T3) \ inline _T1 operator _Op(_T2 __lhs, _T3 __rhs) \ { \ _T1 __retval; \ __retval.__setval(__lhs.__getval() _Op __rhs.__getval()); \ return __retval; \ } #define _DEFINE_DECIMAL_BINARY_OP_BOTH(_Op, _T1, _T2, _T3) \ inline _T1 operator _Op(_T2 __lhs, _T3 __rhs) \ { \ _T1 __retval; \ __retval.__setval(__lhs.__getval() _Op __rhs.__getval()); \ return __retval; \ } #define _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, _T2) \ inline _T1 operator _Op(_T1 __lhs, _T2 __rhs) \ { \ _T1 __retval; \ __retval.__setval(__lhs.__getval() _Op __rhs); \ return __retval; \ } #define _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, _T2) \ inline _T1 operator _Op(_T2 __lhs, _T1 __rhs) \ { \ _T1 __retval; \ __retval.__setval(__lhs _Op __rhs.__getval()); \ return __retval; \ } #define _DEFINE_DECIMAL_BINARY_OP_WITH_INT(_Op, _T1) \ _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, int); \ _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, unsigned int); \ _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, long); \ _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, unsigned long); \ _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, long long); \ _DEFINE_DECIMAL_BINARY_OP_LHS(_Op, _T1, unsigned long long); \ _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, int); \ _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, unsigned int); \ _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, long); \ _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, unsigned long); \ _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, long long); \ _DEFINE_DECIMAL_BINARY_OP_RHS(_Op, _T1, unsigned long long); \ _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal32, decimal32, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(+, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal32, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal64, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal64, decimal64, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(+, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal32, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal64, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(+, decimal128, decimal128, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(+, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal32, decimal32, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(-, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal32, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal64, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal64, decimal64, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(-, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal32, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal64, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(-, decimal128, decimal128, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(-, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal32, decimal32, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(*, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal32, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal64, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal64, decimal64, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(*, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal32, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal64, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(*, decimal128, decimal128, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(*, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal32, decimal32, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(/, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal32, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal64, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal64, decimal64, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(/, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal32, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal64, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal32) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal64) _DEFINE_DECIMAL_BINARY_OP_WITH_DEC(/, decimal128, decimal128, decimal128) _DEFINE_DECIMAL_BINARY_OP_WITH_INT(/, decimal128) #undef _DEFINE_DECIMAL_BINARY_OP_WITH_DEC #undef _DEFINE_DECIMAL_BINARY_OP_BOTH #undef _DEFINE_DECIMAL_BINARY_OP_LHS #undef _DEFINE_DECIMAL_BINARY_OP_RHS #undef _DEFINE_DECIMAL_BINARY_OP_WITH_INT // ISO/IEC TR 24733 3.2.9 Comparison operators. #define _DEFINE_DECIMAL_COMPARISON_BOTH(_Op, _T1, _T2) \ inline bool operator _Op(_T1 __lhs, _T2 __rhs) \ { return __lhs.__getval() _Op __rhs.__getval(); } #define _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _T1, _T2) \ inline bool operator _Op(_T1 __lhs, _T2 __rhs) \ { return __lhs.__getval() _Op __rhs; } #define _DEFINE_DECIMAL_COMPARISON_RHS(_Op, _T1, _T2) \ inline bool operator _Op(_T1 __lhs, _T2 __rhs) \ { return __lhs _Op __rhs.__getval(); } #define _DEFINE_DECIMAL_COMPARISONS(_Op, _Tp) \ _DEFINE_DECIMAL_COMPARISON_BOTH(_Op, _Tp, decimal32) \ _DEFINE_DECIMAL_COMPARISON_BOTH(_Op, _Tp, decimal64) \ _DEFINE_DECIMAL_COMPARISON_BOTH(_Op, _Tp, decimal128) \ _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, int) \ _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, unsigned int) \ _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, long) \ _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, unsigned long) \ _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, long long) \ _DEFINE_DECIMAL_COMPARISON_LHS(_Op, _Tp, unsigned long long) \ _DEFINE_DECIMAL_COMPARISON_RHS(_Op, int, _Tp) \ _DEFINE_DECIMAL_COMPARISON_RHS(_Op, unsigned int, _Tp) \ _DEFINE_DECIMAL_COMPARISON_RHS(_Op, long, _Tp) \ _DEFINE_DECIMAL_COMPARISON_RHS(_Op, unsigned long, _Tp) \ _DEFINE_DECIMAL_COMPARISON_RHS(_Op, long long, _Tp) \ _DEFINE_DECIMAL_COMPARISON_RHS(_Op, unsigned long long, _Tp) _DEFINE_DECIMAL_COMPARISONS(==, decimal32) _DEFINE_DECIMAL_COMPARISONS(==, decimal64) _DEFINE_DECIMAL_COMPARISONS(==, decimal128) _DEFINE_DECIMAL_COMPARISONS(!=, decimal32) _DEFINE_DECIMAL_COMPARISONS(!=, decimal64) _DEFINE_DECIMAL_COMPARISONS(!=, decimal128) _DEFINE_DECIMAL_COMPARISONS(<, decimal32) _DEFINE_DECIMAL_COMPARISONS(<, decimal64) _DEFINE_DECIMAL_COMPARISONS(<, decimal128) _DEFINE_DECIMAL_COMPARISONS(<=, decimal32) _DEFINE_DECIMAL_COMPARISONS(<=, decimal64) _DEFINE_DECIMAL_COMPARISONS(<=, decimal128) _DEFINE_DECIMAL_COMPARISONS(>, decimal32) _DEFINE_DECIMAL_COMPARISONS(>, decimal64) _DEFINE_DECIMAL_COMPARISONS(>, decimal128) _DEFINE_DECIMAL_COMPARISONS(>=, decimal32) _DEFINE_DECIMAL_COMPARISONS(>=, decimal64) _DEFINE_DECIMAL_COMPARISONS(>=, decimal128) #undef _DEFINE_DECIMAL_COMPARISON_BOTH #undef _DEFINE_DECIMAL_COMPARISON_LHS #undef _DEFINE_DECIMAL_COMPARISON_RHS #undef _DEFINE_DECIMAL_COMPARISONS } // namespace decimal _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _GLIBCXX_DECIMAL_IMPL */ 8/tr2/bool_set000064400000016312152526447520007172 0ustar00// TR2 -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file tr2/bool_set * This is a TR2 C++ Library header. */ #ifndef _GLIBCXX_TR2_BOOL_SET #define _GLIBCXX_TR2_BOOL_SET 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr2 { /** * bool_set * * See N2136, Bool_set: multi-valued logic * by Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion. * * The implicit conversion to bool is slippery! I may use the new * explicit conversion. This has been specialized in the language * so that in contexts requiring a bool the conversion happens * implicitly. Thus most objections should be eliminated. */ class bool_set { public: /// Default constructor. constexpr bool_set() : _M_b(_S_false) { } /// Constructor from bool. constexpr bool_set(bool __t) : _M_b(_Bool_set_val(__t)) { } // I'm not sure about this. bool contains(bool_set __b) const { return this->is_singleton() && this->equals(__b); } /// Return true if states are equal. bool equals(bool_set __b) const { return __b._M_b == _M_b; } /// Return true if this is empty. bool is_emptyset() const { return _M_b == _S_empty; } /// Return true if this is indeterminate. bool is_indeterminate() const { return _M_b == _S_indet; } /// Return true if this is false or true (normal boolean). bool is_singleton() const { return _M_b == _S_false || _M_b == _S_true_; } /// Conversion to bool. //explicit operator bool() const { if (! is_singleton()) throw std::bad_cast(); return _M_b; } /// static bool_set indeterminate() { bool_set __b; __b._M_b = _S_indet; return __b; } /// static bool_set emptyset() { bool_set __b; __b._M_b = _S_empty; return __b; } friend bool_set operator!(bool_set __b) { return __b._M_not(); } friend bool_set operator^(bool_set __s, bool_set __t) { return __s._M_xor(__t); } friend bool_set operator|(bool_set __s, bool_set __t) { return __s._M_or(__t); } friend bool_set operator&(bool_set __s, bool_set __t) { return __s._M_and(__t); } friend bool_set operator==(bool_set __s, bool_set __t) { return __s._M_eq(__t); } // These overloads replace the facet additions in the paper! template friend std::basic_ostream& operator<<(std::basic_ostream& __out, bool_set __b) { int __a = __b._M_b; __out << __a; } template friend std::basic_istream& operator>>(std::basic_istream& __in, bool_set& __b) { long __c; __in >> __c; if (__c >= _S_false && __c < _S_empty) __b._M_b = static_cast<_Bool_set_val>(__c); } private: /// enum _Bool_set_val: unsigned char { _S_false = 0, _S_true_ = 1, _S_indet = 2, _S_empty = 3 }; /// Bool set state. _Bool_set_val _M_b; /// bool_set(_Bool_set_val __c) : _M_b(__c) { } /// bool_set _M_not() const { return _S_not[this->_M_b]; } /// bool_set _M_xor(bool_set __b) const { return _S_xor[this->_M_b][__b._M_b]; } /// bool_set _M_or(bool_set __b) const { return _S_or[this->_M_b][__b._M_b]; } /// bool_set _M_and(bool_set __b) const { return _S_and[this->_M_b][__b._M_b]; } /// bool_set _M_eq(bool_set __b) const { return _S_eq[this->_M_b][__b._M_b]; } /// static _Bool_set_val _S_not[4]; /// static _Bool_set_val _S_xor[4][4]; /// static _Bool_set_val _S_or[4][4]; /// static _Bool_set_val _S_and[4][4]; /// static _Bool_set_val _S_eq[4][4]; }; // 20.2.3.2 bool_set values inline bool contains(bool_set __s, bool_set __t) { return __s.contains(__t); } inline bool equals(bool_set __s, bool_set __t) { return __s.equals(__t); } inline bool is_emptyset(bool_set __b) { return __b.is_emptyset(); } inline bool is_indeterminate(bool_set __b) { return __b.is_indeterminate(); } inline bool is_singleton(bool_set __b) { return __b.is_singleton(); } inline bool certainly(bool_set __b) { return ! __b.contains(false); } inline bool possibly(bool_set __b) { return __b.contains(true); } // 20.2.3.3 bool_set set operations inline bool_set set_union(bool __s, bool_set __t) { return bool_set(__s) | __t; } inline bool_set set_union(bool_set __s, bool __t) { return __s | bool_set(__t); } inline bool_set set_union(bool_set __s, bool_set __t) { return __s | __t; } inline bool_set set_intersection(bool __s, bool_set __t) { return bool_set(__s) & __t; } inline bool_set set_intersection(bool_set __s, bool __t) { return __s & bool_set(__t); } inline bool_set set_intersection(bool_set __s, bool_set __t) { return __s & __t; } inline bool_set set_complement(bool_set __b) { return ! __b; } // 20.2.3.4 bool_set logical operators inline bool_set operator^(bool __s, bool_set __t) { return bool_set(__s) ^ __t; } inline bool_set operator^(bool_set __s, bool __t) { return __s ^ bool_set(__t); } inline bool_set operator|(bool __s, bool_set __t) { return bool_set(__s) | __t; } inline bool_set operator|(bool_set __s, bool __t) { return __s | bool_set(__t); } inline bool_set operator&(bool __s, bool_set __t) { return bool_set(__s) & __t; } inline bool_set operator&(bool_set __s, bool __t) { return __s & bool_set(__t); } // 20.2.3.5 bool_set relational operators inline bool_set operator==(bool __s, bool_set __t) { return bool_set(__s) == __t; } inline bool_set operator==(bool_set __s, bool __t) { return __s == bool_set(__t); } inline bool_set operator!=(bool __s, bool_set __t) { return ! (__s == __t); } inline bool_set operator!=(bool_set __s, bool __t) { return ! (__s == __t); } inline bool_set operator!=(bool_set __s, bool_set __t) { return ! (__s == __t); } } _GLIBCXX_END_NAMESPACE_VERSION } #include #endif // _GLIBCXX_TR2_BOOL_SET 8/tr2/dynamic_bitset000064400000103023152526447520010356 0ustar00// TR2 -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file tr2/dynamic_bitset * This is a TR2 C++ Library header. */ #ifndef _GLIBCXX_TR2_DYNAMIC_BITSET #define _GLIBCXX_TR2_DYNAMIC_BITSET 1 #pragma GCC system_header #include #include #include #include #include #include // For fill #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr2 { /** * @defgroup dynamic_bitset Dynamic Bitset. * @ingroup extensions * * @{ */ /** * Base class, general case. * * See documentation for dynamic_bitset. */ template> struct __dynamic_bitset_base { static_assert(std::is_unsigned<_WordT>::value, "template argument " "_WordT not an unsigned integral type"); typedef _WordT block_type; typedef _Alloc allocator_type; typedef size_t size_type; static const size_type _S_bits_per_block = __CHAR_BIT__ * sizeof(block_type); static const size_type npos = static_cast(-1); /// 0 is the least significant word. std::vector _M_w; explicit __dynamic_bitset_base(const allocator_type& __alloc) : _M_w(__alloc) { } __dynamic_bitset_base() = default; __dynamic_bitset_base(const __dynamic_bitset_base&) = default; __dynamic_bitset_base(__dynamic_bitset_base&& __b) = default; __dynamic_bitset_base& operator=(const __dynamic_bitset_base&) = default; __dynamic_bitset_base& operator=(__dynamic_bitset_base&&) = default; ~__dynamic_bitset_base() = default; explicit __dynamic_bitset_base(size_type __nbits, unsigned long long __val = 0ULL, const allocator_type& __alloc = allocator_type()) : _M_w(__nbits / _S_bits_per_block + (__nbits % _S_bits_per_block > 0), block_type(0), __alloc) { if (__nbits < std::numeric_limits::digits) __val &= ~(-1ULL << __nbits); if (__val == 0) return; if _GLIBCXX17_CONSTEXPR (sizeof(__val) == sizeof(block_type)) _M_w[0] = __val; else { const size_t __n = std::min(_M_w.size(), sizeof(__val) / sizeof(block_type)); for (size_t __i = 0; __val && __i < __n; ++__i) { _M_w[__i] = static_cast(__val); __val >>= _S_bits_per_block; } } } void _M_swap(__dynamic_bitset_base& __b) noexcept { this->_M_w.swap(__b._M_w); } void _M_clear() noexcept { this->_M_w.clear(); } void _M_resize(size_t __nbits, bool __value) { size_t __sz = __nbits / _S_bits_per_block; if (__nbits % _S_bits_per_block > 0) ++__sz; if (__sz != this->_M_w.size()) { block_type __val = 0; if (__value) __val = std::numeric_limits::max(); this->_M_w.resize(__sz, __val); } } allocator_type _M_get_allocator() const noexcept { return this->_M_w.get_allocator(); } static size_type _S_whichword(size_type __pos) noexcept { return __pos / _S_bits_per_block; } static size_type _S_whichbyte(size_type __pos) noexcept { return (__pos % _S_bits_per_block) / __CHAR_BIT__; } static size_type _S_whichbit(size_type __pos) noexcept { return __pos % _S_bits_per_block; } static block_type _S_maskbit(size_type __pos) noexcept { return (static_cast(1)) << _S_whichbit(__pos); } block_type& _M_getword(size_type __pos) noexcept { return this->_M_w[_S_whichword(__pos)]; } block_type _M_getword(size_type __pos) const noexcept { return this->_M_w[_S_whichword(__pos)]; } block_type& _M_hiword() noexcept { return this->_M_w[_M_w.size() - 1]; } block_type _M_hiword() const noexcept { return this->_M_w[_M_w.size() - 1]; } void _M_do_and(const __dynamic_bitset_base& __x) noexcept { if (__x._M_w.size() == this->_M_w.size()) for (size_t __i = 0; __i < this->_M_w.size(); ++__i) this->_M_w[__i] &= __x._M_w[__i]; else return; } void _M_do_or(const __dynamic_bitset_base& __x) noexcept { if (__x._M_w.size() == this->_M_w.size()) for (size_t __i = 0; __i < this->_M_w.size(); ++__i) this->_M_w[__i] |= __x._M_w[__i]; else return; } void _M_do_xor(const __dynamic_bitset_base& __x) noexcept { if (__x._M_w.size() == this->_M_w.size()) for (size_t __i = 0; __i < this->_M_w.size(); ++__i) this->_M_w[__i] ^= __x._M_w[__i]; else return; } void _M_do_dif(const __dynamic_bitset_base& __x) noexcept { if (__x._M_w.size() == this->_M_w.size()) for (size_t __i = 0; __i < this->_M_w.size(); ++__i) this->_M_w[__i] &= ~__x._M_w[__i]; else return; } void _M_do_left_shift(size_t __shift); void _M_do_right_shift(size_t __shift); void _M_do_flip() noexcept { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) this->_M_w[__i] = ~this->_M_w[__i]; } void _M_do_set() noexcept { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) this->_M_w[__i] = static_cast(-1); } void _M_do_reset() noexcept { std::fill(_M_w.begin(), _M_w.end(), static_cast(0)); } bool _M_is_equal(const __dynamic_bitset_base& __x) const noexcept { if (__x._M_w.size() == this->_M_w.size()) { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i] != __x._M_w[__i]) return false; return true; } else return false; } bool _M_is_less(const __dynamic_bitset_base& __x) const noexcept { if (__x._M_w.size() == this->_M_w.size()) { for (size_t __i = this->_M_w.size(); __i > 0; --__i) { if (this->_M_w[__i-1] < __x._M_w[__i-1]) return true; else if (this->_M_w[__i-1] > __x._M_w[__i-1]) return false; } return false; } else return false; } size_t _M_are_all_aux() const noexcept { for (size_t __i = 0; __i < this->_M_w.size() - 1; ++__i) if (_M_w[__i] != static_cast(-1)) return 0; return ((this->_M_w.size() - 1) * _S_bits_per_block + __builtin_popcountll(this->_M_hiword())); } bool _M_is_any() const noexcept { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i] != static_cast(0)) return true; return false; } bool _M_is_subset_of(const __dynamic_bitset_base& __b) noexcept { if (__b._M_w.size() == this->_M_w.size()) { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i] != (this->_M_w[__i] | __b._M_w[__i])) return false; return true; } else return false; } bool _M_is_proper_subset_of(const __dynamic_bitset_base& __b) const noexcept { if (this->is_subset_of(__b)) { if (*this == __b) return false; else return true; } else return false; } size_t _M_do_count() const noexcept { size_t __result = 0; for (size_t __i = 0; __i < this->_M_w.size(); ++__i) __result += __builtin_popcountll(this->_M_w[__i]); return __result; } size_type _M_size() const noexcept { return this->_M_w.size(); } unsigned long _M_do_to_ulong() const; unsigned long long _M_do_to_ullong() const; // find first "on" bit size_type _M_do_find_first(size_t __not_found) const; // find the next "on" bit that follows "prev" size_type _M_do_find_next(size_t __prev, size_t __not_found) const; // do append of block void _M_do_append_block(block_type __block, size_type __pos) { size_t __offset = __pos % _S_bits_per_block; if (__offset == 0) this->_M_w.push_back(__block); else { this->_M_hiword() |= (__block << __offset); this->_M_w.push_back(__block >> (_S_bits_per_block - __offset)); } } }; /** * @brief The %dynamic_bitset class represents a sequence of bits. * * See N2050, * Proposal to Add a Dynamically Sizeable Bitset to the Standard Library. * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2050.pdf * * In the general unoptimized case, storage is allocated in * word-sized blocks. Let B be the number of bits in a word, then * (Nb+(B-1))/B words will be used for storage. B - Nb%B bits are * unused. (They are the high-order bits in the highest word.) It * is a class invariant that those unused bits are always zero. * * If you think of %dynamic_bitset as "a simple array of bits," be * aware that your mental picture is reversed: a %dynamic_bitset * behaves the same way as bits in integers do, with the bit at * index 0 in the "least significant / right-hand" position, and * the bit at index Nb-1 in the "most significant / left-hand" * position. Thus, unlike other containers, a %dynamic_bitset's * index "counts from right to left," to put it very loosely. * * This behavior is preserved when translating to and from strings. * For example, the first line of the following program probably * prints "b('a') is 0001100001" on a modern ASCII system. * * @code * #include * #include * #include * * using namespace std; * * int main() * { * long a = 'a'; * dynamic_bitset<> b(a); * * cout << "b('a') is " << b << endl; * * ostringstream s; * s << b; * string str = s.str(); * cout << "index 3 in the string is " << str[3] << " but\n" * << "index 3 in the bitset is " << b[3] << endl; * } * @endcode * * Most of the actual code isn't contained in %dynamic_bitset<> * itself, but in the base class __dynamic_bitset_base. The base * class works with whole words, not with individual bits. This * allows us to specialize __dynamic_bitset_base for the important * special case where the %dynamic_bitset is only a single word. * * Extra confusion can result due to the fact that the storage for * __dynamic_bitset_base @e is a vector, and is indexed as such. This is * carefully encapsulated. */ template> class dynamic_bitset : private __dynamic_bitset_base<_WordT, _Alloc> { static_assert(std::is_unsigned<_WordT>::value, "template argument " "_WordT not an unsigned integral type"); public: typedef __dynamic_bitset_base<_WordT, _Alloc> _Base; typedef _WordT block_type; typedef _Alloc allocator_type; typedef size_t size_type; static const size_type bits_per_block = __CHAR_BIT__ * sizeof(block_type); // Use this: constexpr size_type std::numeric_limits::max(). static const size_type npos = static_cast(-1); private: // Clear the unused bits in the uppermost word. void _M_do_sanitize() { size_type __shift = this->_M_Nb % bits_per_block; if (__shift > 0) this->_M_hiword() &= block_type(~(block_type(-1) << __shift)); } // Set the unused bits in the uppermost word. void _M_do_fill() { size_type __shift = this->_M_Nb % bits_per_block; if (__shift > 0) this->_M_hiword() |= block_type(block_type(-1) << __shift); } /** * These versions of single-bit set, reset, flip, and test * do no range checking. */ dynamic_bitset& _M_unchecked_set(size_type __pos) noexcept { this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); return *this; } dynamic_bitset& _M_unchecked_set(size_type __pos, int __val) noexcept { if (__val) this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); else this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); return *this; } dynamic_bitset& _M_unchecked_reset(size_type __pos) noexcept { this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); return *this; } dynamic_bitset& _M_unchecked_flip(size_type __pos) noexcept { this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); return *this; } bool _M_unchecked_test(size_type __pos) const noexcept { return ((this->_M_getword(__pos) & _Base::_S_maskbit(__pos)) != static_cast<_WordT>(0)); } size_type _M_Nb = 0; public: /** * This encapsulates the concept of a single bit. An instance * of this class is a proxy for an actual bit; this way the * individual bit operations are done as faster word-size * bitwise instructions. * * Most users will never need to use this class directly; * conversions to and from bool are automatic and should be * transparent. Overloaded operators help to preserve the * illusion. * * (On a typical system, this "bit %reference" is 64 times the * size of an actual bit. Ha.) */ class reference { friend class dynamic_bitset; block_type *_M_wp; size_type _M_bpos; public: reference(dynamic_bitset& __b, size_type __pos) noexcept { this->_M_wp = &__b._M_getword(__pos); this->_M_bpos = _Base::_S_whichbit(__pos); } // For b[i] = __x; reference& operator=(bool __x) noexcept { if (__x) *this->_M_wp |= _Base::_S_maskbit(this->_M_bpos); else *this->_M_wp &= ~_Base::_S_maskbit(this->_M_bpos); return *this; } // For b[i] = b[__j]; reference& operator=(const reference& __j) noexcept { if ((*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos))) *this->_M_wp |= _Base::_S_maskbit(this->_M_bpos); else *this->_M_wp &= ~_Base::_S_maskbit(this->_M_bpos); return *this; } // Flips the bit bool operator~() const noexcept { return (*(_M_wp) & _Base::_S_maskbit(this->_M_bpos)) == 0; } // For __x = b[i]; operator bool() const noexcept { return (*(this->_M_wp) & _Base::_S_maskbit(this->_M_bpos)) != 0; } // For b[i].flip(); reference& flip() noexcept { *this->_M_wp ^= _Base::_S_maskbit(this->_M_bpos); return *this; } }; friend class reference; typedef bool const_reference; // 23.3.5.1 constructors: /// All bits set to zero. dynamic_bitset() = default; /// All bits set to zero. explicit dynamic_bitset(const allocator_type& __alloc) : _Base(__alloc) { } /// Initial bits bitwise-copied from a single word (others set to zero). explicit dynamic_bitset(size_type __nbits, unsigned long long __val = 0ULL, const allocator_type& __alloc = allocator_type()) : _Base(__nbits, __val, __alloc), _M_Nb(__nbits) { } dynamic_bitset(initializer_list __il, const allocator_type& __alloc = allocator_type()) : _Base(__alloc) { this->append(__il); } /** * @brief Use a subset of a string. * @param __str A string of '0' and '1' characters. * @param __pos Index of the first character in @p __str to use. * @param __n The number of characters to copy. * @param __zero The character to use for unset bits. * @param __one The character to use for set bits. * @param __alloc An allocator. * @throw std::out_of_range If @p __pos is bigger the size of @p __str. * @throw std::invalid_argument If a character appears in the string * which is neither '0' nor '1'. */ template explicit dynamic_bitset(const std::basic_string<_CharT, _Traits, _Alloc1>& __str, typename basic_string<_CharT,_Traits,_Alloc1>::size_type __pos = 0, typename basic_string<_CharT,_Traits,_Alloc1>::size_type __n = std::basic_string<_CharT, _Traits, _Alloc1>::npos, _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'), const allocator_type& __alloc = allocator_type()) : _Base(__alloc) { if (__pos > __str.size()) __throw_out_of_range(__N("dynamic_bitset::bitset initial position " "not valid")); // Watch for npos. this->_M_Nb = (__n > __str.size() ? __str.size() - __pos : __n); this->resize(this->_M_Nb); this->_M_copy_from_string(__str, __pos, __n); } /** * @brief Construct from a string. * @param __str A string of '0' and '1' characters. * @param __alloc An allocator. * @throw std::invalid_argument If a character appears in the string * which is neither '0' nor '1'. */ explicit dynamic_bitset(const char* __str, const allocator_type& __alloc = allocator_type()) : _Base(__builtin_strlen(__str), 0ULL, __alloc), _M_Nb(__builtin_strlen(__str)) { this->_M_copy_from_ptr(__str, _M_Nb, 0, _M_Nb); } /// Copy constructor. dynamic_bitset(const dynamic_bitset&) = default; /// Move constructor. dynamic_bitset(dynamic_bitset&& __b) noexcept : _Base(std::move(__b)), _M_Nb(__b._M_Nb) { __b.clear(); } /// Swap with another bitset. void swap(dynamic_bitset& __b) noexcept { this->_M_swap(__b); std::swap(this->_M_Nb, __b._M_Nb); } /// Copy assignment operator. dynamic_bitset& operator=(const dynamic_bitset&) = default; /// Move assignment operator. dynamic_bitset& operator=(dynamic_bitset&& __b) noexcept(std::is_nothrow_move_assignable<_Base>::value) { static_cast<_Base&>(*this) = static_cast<_Base&&>(__b); _M_Nb = __b._M_Nb; if _GLIBCXX17_CONSTEXPR (std::is_nothrow_move_assignable<_Base>::value) __b._M_Nb = 0; else if (get_allocator() == __b.get_allocator()) __b._M_Nb = 0; return *this; } /** * @brief Return the allocator for the bitset. */ allocator_type get_allocator() const noexcept { return this->_M_get_allocator(); } /** * @brief Resize the bitset. */ void resize(size_type __nbits, bool __value = false) { if (__value) this->_M_do_fill(); this->_M_resize(__nbits, __value); this->_M_Nb = __nbits; this->_M_do_sanitize(); } /** * @brief Clear the bitset. */ void clear() { this->_M_clear(); this->_M_Nb = 0; } /** * @brief Push a bit onto the high end of the bitset. */ void push_back(bool __bit) { if (size_t __offset = this->size() % bits_per_block == 0) this->_M_do_append_block(block_type(0), this->_M_Nb); ++this->_M_Nb; this->_M_unchecked_set(this->_M_Nb, __bit); } // XXX why is there no pop_back() member in the proposal? /** * @brief Append a block. */ void append(block_type __block) { this->_M_do_append_block(__block, this->_M_Nb); this->_M_Nb += bits_per_block; } /** * @brief */ void append(initializer_list __il) { this->append(__il.begin(), __il.end()); } /** * @brief Append an iterator range of blocks. */ template void append(_BlockInputIterator __first, _BlockInputIterator __last) { for (; __first != __last; ++__first) this->append(*__first); } // 23.3.5.2 dynamic_bitset operations: //@{ /** * @brief Operations on dynamic_bitsets. * @param __rhs A same-sized dynamic_bitset. * * These should be self-explanatory. */ dynamic_bitset& operator&=(const dynamic_bitset& __rhs) { this->_M_do_and(__rhs); return *this; } dynamic_bitset& operator&=(dynamic_bitset&& __rhs) { this->_M_do_and(std::move(__rhs)); return *this; } dynamic_bitset& operator|=(const dynamic_bitset& __rhs) { this->_M_do_or(__rhs); return *this; } dynamic_bitset& operator^=(const dynamic_bitset& __rhs) { this->_M_do_xor(__rhs); return *this; } dynamic_bitset& operator-=(const dynamic_bitset& __rhs) { this->_M_do_dif(__rhs); return *this; } //@} //@{ /** * @brief Operations on dynamic_bitsets. * @param __pos The number of places to shift. * * These should be self-explanatory. */ dynamic_bitset& operator<<=(size_type __pos) { if (__builtin_expect(__pos < this->_M_Nb, 1)) { this->_M_do_left_shift(__pos); this->_M_do_sanitize(); } else this->_M_do_reset(); return *this; } dynamic_bitset& operator>>=(size_type __pos) { if (__builtin_expect(__pos < this->_M_Nb, 1)) { this->_M_do_right_shift(__pos); this->_M_do_sanitize(); } else this->_M_do_reset(); return *this; } //@} // Set, reset, and flip. /** * @brief Sets every bit to true. */ dynamic_bitset& set() { this->_M_do_set(); this->_M_do_sanitize(); return *this; } /** * @brief Sets a given bit to a particular value. * @param __pos The index of the bit. * @param __val Either true or false, defaults to true. * @throw std::out_of_range If @a __pos is bigger the size of the %set. */ dynamic_bitset& set(size_type __pos, bool __val = true) { if (__pos >= _M_Nb) __throw_out_of_range(__N("dynamic_bitset::set")); return this->_M_unchecked_set(__pos, __val); } /** * @brief Sets every bit to false. */ dynamic_bitset& reset() { this->_M_do_reset(); return *this; } /** * @brief Sets a given bit to false. * @param __pos The index of the bit. * @throw std::out_of_range If @a __pos is bigger the size of the %set. * * Same as writing @c set(__pos, false). */ dynamic_bitset& reset(size_type __pos) { if (__pos >= _M_Nb) __throw_out_of_range(__N("dynamic_bitset::reset")); return this->_M_unchecked_reset(__pos); } /** * @brief Toggles every bit to its opposite value. */ dynamic_bitset& flip() { this->_M_do_flip(); this->_M_do_sanitize(); return *this; } /** * @brief Toggles a given bit to its opposite value. * @param __pos The index of the bit. * @throw std::out_of_range If @a __pos is bigger the size of the %set. */ dynamic_bitset& flip(size_type __pos) { if (__pos >= _M_Nb) __throw_out_of_range(__N("dynamic_bitset::flip")); return this->_M_unchecked_flip(__pos); } /// See the no-argument flip(). dynamic_bitset operator~() const { return dynamic_bitset<_WordT, _Alloc>(*this).flip(); } //@{ /** * @brief Array-indexing support. * @param __pos Index into the %dynamic_bitset. * @return A bool for a 'const %dynamic_bitset'. For non-const * bitsets, an instance of the reference proxy class. * @note These operators do no range checking and throw no * exceptions, as required by DR 11 to the standard. */ reference operator[](size_type __pos) { return reference(*this,__pos); } const_reference operator[](size_type __pos) const { return _M_unchecked_test(__pos); } //@} /** * @brief Returns a numerical interpretation of the %dynamic_bitset. * @return The integral equivalent of the bits. * @throw std::overflow_error If there are too many bits to be * represented in an @c unsigned @c long. */ unsigned long to_ulong() const { return this->_M_do_to_ulong(); } /** * @brief Returns a numerical interpretation of the %dynamic_bitset. * @return The integral equivalent of the bits. * @throw std::overflow_error If there are too many bits to be * represented in an @c unsigned @c long. */ unsigned long long to_ullong() const { return this->_M_do_to_ullong(); } /** * @brief Returns a character interpretation of the %dynamic_bitset. * @return The string equivalent of the bits. * * Note the ordering of the bits: decreasing character positions * correspond to increasing bit positions (see the main class notes for * an example). */ template, typename _Alloc1 = std::allocator<_CharT>> std::basic_string<_CharT, _Traits, _Alloc1> to_string(_CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const { std::basic_string<_CharT, _Traits, _Alloc1> __result; _M_copy_to_string(__result, __zero, __one); return __result; } // Helper functions for string operations. template, typename _CharT = typename _Traits::char_type> void _M_copy_from_ptr(const _CharT*, size_t, size_t, size_t, _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')); template void _M_copy_from_string(const basic_string<_CharT, _Traits, _Alloc1>& __str, size_t __pos, size_t __n, _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) { _M_copy_from_ptr<_Traits>(__str.data(), __str.size(), __pos, __n, __zero, __one); } template void _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc1>& __str, _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) const; /// Returns the number of bits which are set. size_type count() const noexcept { return this->_M_do_count(); } /// Returns the total number of bits. size_type size() const noexcept { return this->_M_Nb; } /// Returns the total number of blocks. size_type num_blocks() const noexcept { return this->_M_size(); } /// Returns true if the dynamic_bitset is empty. bool empty() const noexcept { return (this->_M_Nb == 0); } /// Returns the maximum size of a dynamic_bitset object having the same /// type as *this. /// The real answer is max() * bits_per_block but is likely to overflow. constexpr size_type max_size() noexcept { return std::numeric_limits::max(); } /** * @brief Tests the value of a bit. * @param __pos The index of a bit. * @return The value at @a __pos. * @throw std::out_of_range If @a __pos is bigger the size of the %set. */ bool test(size_type __pos) const { if (__pos >= _M_Nb) __throw_out_of_range(__N("dynamic_bitset::test")); return _M_unchecked_test(__pos); } /** * @brief Tests whether all the bits are on. * @return True if all the bits are set. */ bool all() const { return this->_M_are_all_aux() == _M_Nb; } /** * @brief Tests whether any of the bits are on. * @return True if at least one bit is set. */ bool any() const { return this->_M_is_any(); } /** * @brief Tests whether any of the bits are on. * @return True if none of the bits are set. */ bool none() const { return !this->_M_is_any(); } //@{ /// Self-explanatory. dynamic_bitset operator<<(size_type __pos) const { return dynamic_bitset(*this) <<= __pos; } dynamic_bitset operator>>(size_type __pos) const { return dynamic_bitset(*this) >>= __pos; } //@} /** * @brief Finds the index of the first "on" bit. * @return The index of the first bit set, or size() if not found. * @sa find_next */ size_type find_first() const { return this->_M_do_find_first(this->_M_Nb); } /** * @brief Finds the index of the next "on" bit after prev. * @return The index of the next bit set, or size() if not found. * @param __prev Where to start searching. * @sa find_first */ size_type find_next(size_t __prev) const { return this->_M_do_find_next(__prev, this->_M_Nb); } bool is_subset_of(const dynamic_bitset& __b) const { return this->_M_is_subset_of(__b); } bool is_proper_subset_of(const dynamic_bitset& __b) const { return this->_M_is_proper_subset_of(__b); } friend bool operator==(const dynamic_bitset& __lhs, const dynamic_bitset& __rhs) noexcept { return __lhs._M_Nb == __rhs._M_Nb && __lhs._M_is_equal(__rhs); } friend bool operator<(const dynamic_bitset& __lhs, const dynamic_bitset& __rhs) noexcept { return __lhs._M_is_less(__rhs) || __lhs._M_Nb < __rhs._M_Nb; } }; template template inline void dynamic_bitset<_WordT, _Alloc>:: _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc1>& __str, _CharT __zero, _CharT __one) const { __str.assign(_M_Nb, __zero); for (size_t __i = _M_Nb; __i > 0; --__i) if (_M_unchecked_test(__i - 1)) _Traits::assign(__str[_M_Nb - __i], __one); } //@{ /// These comparisons for equality/inequality are, well, @e bitwise. template inline bool operator!=(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return !(__lhs == __rhs); } template inline bool operator<=(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return !(__lhs > __rhs); } template inline bool operator>(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return __rhs < __lhs; } template inline bool operator>=(const dynamic_bitset<_WordT, _Alloc>& __lhs, const dynamic_bitset<_WordT, _Alloc>& __rhs) { return !(__lhs < __rhs); } //@} // 23.3.5.3 bitset operations: //@{ /** * @brief Global bitwise operations on bitsets. * @param __x A bitset. * @param __y A bitset of the same size as @a __x. * @return A new bitset. * * These should be self-explanatory. */ template inline dynamic_bitset<_WordT, _Alloc> operator&(const dynamic_bitset<_WordT, _Alloc>& __x, const dynamic_bitset<_WordT, _Alloc>& __y) { dynamic_bitset<_WordT, _Alloc> __result(__x); __result &= __y; return __result; } template inline dynamic_bitset<_WordT, _Alloc> operator|(const dynamic_bitset<_WordT, _Alloc>& __x, const dynamic_bitset<_WordT, _Alloc>& __y) { dynamic_bitset<_WordT, _Alloc> __result(__x); __result |= __y; return __result; } template inline dynamic_bitset<_WordT, _Alloc> operator^(const dynamic_bitset<_WordT, _Alloc>& __x, const dynamic_bitset<_WordT, _Alloc>& __y) { dynamic_bitset<_WordT, _Alloc> __result(__x); __result ^= __y; return __result; } template inline dynamic_bitset<_WordT, _Alloc> operator-(const dynamic_bitset<_WordT, _Alloc>& __x, const dynamic_bitset<_WordT, _Alloc>& __y) { dynamic_bitset<_WordT, _Alloc> __result(__x); __result -= __y; return __result; } //@} /// Stream output operator for dynamic_bitset. template inline std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const dynamic_bitset<_WordT, _Alloc>& __x) { std::basic_string<_CharT, _Traits> __tmp; const ctype<_CharT>& __ct = use_facet>(__os.getloc()); __x._M_copy_to_string(__tmp, __ct.widen('0'), __ct.widen('1')); return __os << __tmp; } /** * @} */ } // tr2 _GLIBCXX_END_NAMESPACE_VERSION } // std #include #endif /* _GLIBCXX_TR2_DYNAMIC_BITSET */ 8/tr2/bool_set.tcc000064400000020177152526447520007746 0ustar00// TR2 support files -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file tr2/bool_set.tcc * This is a TR2 C++ Library header. */ #ifndef _GLIBCXX_TR2_BOOL_SET_TCC #define _GLIBCXX_TR2_BOOL_SET_TCC 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr2 { bool_set::_Bool_set_val bool_set::_S_not[4] = { _S_true_, _S_false, _S_indet, _S_empty }; bool_set::_Bool_set_val bool_set::_S_xor[4][4] = { { _S_false, _S_true_, _S_indet, _S_empty }, { _S_true_, _S_false, _S_indet, _S_empty }, { _S_indet, _S_indet, _S_indet, _S_empty }, { _S_empty, _S_empty, _S_empty, _S_empty } }; bool_set::_Bool_set_val bool_set::_S_or[4][4] = { { _S_false, _S_true_, _S_indet, _S_empty }, { _S_true_, _S_true_, _S_true_, _S_empty }, { _S_indet, _S_true_, _S_indet, _S_empty }, { _S_empty, _S_empty, _S_empty, _S_empty } }; bool_set::_Bool_set_val bool_set::_S_and[4][4] = { { _S_false, _S_false, _S_false, _S_empty }, { _S_false, _S_true_, _S_indet, _S_empty }, { _S_false, _S_indet, _S_indet, _S_empty }, { _S_empty, _S_empty, _S_empty, _S_empty } }; bool_set::_Bool_set_val bool_set::_S_eq[4][4] = { { _S_true_, _S_false, _S_indet, _S_empty }, { _S_false, _S_true_, _S_indet, _S_empty }, { _S_indet, _S_indet, _S_indet, _S_empty }, { _S_empty, _S_empty, _S_empty, _S_empty } }; } _GLIBCXX_END_NAMESPACE_VERSION } // I object to these things. // The stuff in locale facets are for basic types. // I think we could hack operator<< and operator>>. /** * @brief Numeric parsing. * * Parses the input stream into the bool @a v. It does so by calling * num_get::do_get(). * * If ios_base::boolalpha is set, attempts to read * ctype::truename() or ctype::falsename(). Sets * @a v to true or false if successful. Sets err to * ios_base::failbit if reading the string fails. Sets err to * ios_base::eofbit if the stream is emptied. * * If ios_base::boolalpha is not set, proceeds as with reading a long, * except if the value is 1, sets @a v to true, if the value is 0, sets * @a v to false, and otherwise set err to ios_base::failbit. * * @param in Start of input stream. * @param end End of input stream. * @param io Source of locale and flags. * @param err Error flags to set. * @param v Value to format and insert. * @return Iterator after reading. iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, bool& __v) const { return this->do_get(__in, __end, __io, __err, __v); } */ /* template _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, bool_set& __v) const { if (!(__io.flags() & ios_base::boolalpha)) { // Parse bool values as long. // NB: We can't just call do_get(long) here, as it might // refer to a derived class. long __l = -1; __beg = _M_extract_int(__beg, __end, __io, __err, __l); if (__c >= _S_false && __c < _S_empty) __b._M_b = static_cast<_Bool_set_val>(__c); else { // What should we do here? __v = true; __err = ios_base::failbit; if (__beg == __end) __err |= ios_base::eofbit; } } else { // Parse bool values as alphanumeric. typedef __numpunct_cache<_CharT> __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); bool __testf = true; bool __testt = true; bool __donef = __lc->_M_falsename_size == 0; bool __donet = __lc->_M_truename_size == 0; bool __testeof = false; size_t __n = 0; while (!__donef || !__donet) { if (__beg == __end) { __testeof = true; break; } const char_type __c = *__beg; if (!__donef) __testf = __c == __lc->_M_falsename[__n]; if (!__testf && __donet) break; if (!__donet) __testt = __c == __lc->_M_truename[__n]; if (!__testt && __donef) break; if (!__testt && !__testf) break; ++__n; ++__beg; __donef = !__testf || __n >= __lc->_M_falsename_size; __donet = !__testt || __n >= __lc->_M_truename_size; } if (__testf && __n == __lc->_M_falsename_size && __n) { __v = false; if (__testt && __n == __lc->_M_truename_size) __err = ios_base::failbit; else __err = __testeof ? ios_base::eofbit : ios_base::goodbit; } else if (__testt && __n == __lc->_M_truename_size && __n) { __v = true; __err = __testeof ? ios_base::eofbit : ios_base::goodbit; } else { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 23. Num_get overflow result. __v = false; __err = ios_base::failbit; if (__testeof) __err |= ios_base::eofbit; } } return __beg; } */ /** * @brief Numeric formatting. * * Formats the boolean @a v and inserts it into a stream. It does so * by calling num_put::do_put(). * * If ios_base::boolalpha is set, writes ctype::truename() or * ctype::falsename(). Otherwise formats @a v as an int. * * @param s Stream to write to. * @param io Source of locale and flags. * @param fill Char_type to use for filling. * @param v Value to format and insert. * @return Iterator after writing. iter_type put(iter_type __s, ios_base& __f, char_type __fill, bool __v) const { return this->do_put(__s, __f, __fill, __v); } */ /* template _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, bool_set __v) const { const ios_base::fmtflags __flags = __io.flags(); if ((__flags & ios_base::boolalpha) == 0) { const long __l = __v; __s = _M_insert_int(__s, __io, __fill, __l); } else { typedef __numpunct_cache<_CharT> __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); const _CharT* __name = __v ? __lc->_M_truename : __lc->_M_falsename; int __len = __v ? __lc->_M_truename_size : __lc->_M_falsename_size; const streamsize __w = __io.width(); if (__w > static_cast(__len)) { const streamsize __plen = __w - __len; _CharT* __ps = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __plen)); char_traits<_CharT>::assign(__ps, __plen, __fill); __io.width(0); if ((__flags & ios_base::adjustfield) == ios_base::left) { __s = std::__write(__s, __name, __len); __s = std::__write(__s, __ps, __plen); } else { __s = std::__write(__s, __ps, __plen); __s = std::__write(__s, __name, __len); } return __s; } __io.width(0); __s = std::__write(__s, __name, __len); } return __s; } */ #endif // _GLIBCXX_TR2_BOOL_SET_TCC 8/tr2/ratio000064400000004122152526447520006476 0ustar00// TR2 -*- C++ -*- // Copyright (C) 2010-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file tr2/ratio * This is a TR2 C++ Library header. */ #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr2 { template (std::numeric_limits::digits)> struct __safe_lshift { static const intmax_t __value = 0; }; template struct __safe_lshift<_Pn, _Bit, true> { static const intmax_t __value = _Pn << _Bit; }; /// Add binary prefixes (IEC 60027-2 A.2 and ISO/IEC 80000). typedef ratio<__safe_lshift<1, 10>::__value, 1> kibi; typedef ratio<__safe_lshift<1, 20>::__value, 1> mebi; typedef ratio<__safe_lshift<1, 30>::__value, 1> gibi; typedef ratio<__safe_lshift<1, 40>::__value, 1> tebi; typedef ratio<__safe_lshift<1, 50>::__value, 1> pebi; typedef ratio<__safe_lshift<1, 60>::__value, 1> exbi; //typedef ratio<__safe_lshift<1, 70>::__value, 1> zebi; //typedef ratio<__safe_lshift<1, 80>::__value, 1> yobi; } _GLIBCXX_END_NAMESPACE_VERSION } 8/tr2/type_traits000064400000005213152526447520007731 0ustar00// TR2 -*- C++ -*- // Copyright (C) 2011-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file tr2/type_traits * This is a TR2 C++ Library header. */ #ifndef _GLIBCXX_TR2_TYPE_TRAITS #define _GLIBCXX_TR2_TYPE_TRAITS 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr2 { /** * @addtogroup metaprogramming * @{ */ /** * See N2965: Type traits and base classes * by Michael Spertus */ /** * Simple typelist. Compile-time list of types. */ template struct __reflection_typelist; /// Specialization for an empty typelist. template<> struct __reflection_typelist<> { typedef std::true_type empty; }; /// Partial specialization. template struct __reflection_typelist<_First, _Rest...> { typedef std::false_type empty; struct first { typedef _First type; }; struct rest { typedef __reflection_typelist<_Rest...> type; }; }; /// Sequence abstraction metafunctions for manipulating a typelist. /// Enumerate all the base classes of a class. Form of a typelist. template struct bases { typedef __reflection_typelist<__bases(_Tp)...> type; }; /// Enumerate all the direct base classes of a class. Form of a typelist. template struct direct_bases { typedef __reflection_typelist<__direct_bases(_Tp)...> type; }; /// @} group metaprogramming } _GLIBCXX_END_NAMESPACE_VERSION } #endif // _GLIBCXX_TR2_TYPE_TRAITS 8/tr2/dynamic_bitset.tcc000064400000021335152526447520011133 0ustar00// TR2 -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file tr2/dynamic_bitset.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{tr2/dynamic_bitset} */ #ifndef _GLIBCXX_TR2_DYNAMIC_BITSET_TCC #define _GLIBCXX_TR2_DYNAMIC_BITSET_TCC 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr2 { // Definitions of non-inline functions from __dynamic_bitset_base. template void __dynamic_bitset_base<_WordT, _Alloc>::_M_do_left_shift(size_t __shift) { if (__builtin_expect(__shift != 0, 1)) { const size_t __wshift = __shift / _S_bits_per_block; const size_t __offset = __shift % _S_bits_per_block; if (__offset == 0) for (size_t __n = this->_M_w.size() - 1; __n >= __wshift; --__n) this->_M_w[__n] = this->_M_w[__n - __wshift]; else { const size_t __sub_offset = _S_bits_per_block - __offset; for (size_t __n = _M_w.size() - 1; __n > __wshift; --__n) this->_M_w[__n] = ((this->_M_w[__n - __wshift] << __offset) | (this->_M_w[__n - __wshift - 1] >> __sub_offset)); this->_M_w[__wshift] = this->_M_w[0] << __offset; } //// std::fill(this->_M_w.begin(), this->_M_w.begin() + __wshift, //// static_cast<_WordT>(0)); } } template void __dynamic_bitset_base<_WordT, _Alloc>::_M_do_right_shift(size_t __shift) { if (__builtin_expect(__shift != 0, 1)) { const size_t __wshift = __shift / _S_bits_per_block; const size_t __offset = __shift % _S_bits_per_block; const size_t __limit = this->_M_w.size() - __wshift - 1; if (__offset == 0) for (size_t __n = 0; __n <= __limit; ++__n) this->_M_w[__n] = this->_M_w[__n + __wshift]; else { const size_t __sub_offset = (_S_bits_per_block - __offset); for (size_t __n = 0; __n < __limit; ++__n) this->_M_w[__n] = ((this->_M_w[__n + __wshift] >> __offset) | (this->_M_w[__n + __wshift + 1] << __sub_offset)); this->_M_w[__limit] = this->_M_w[_M_w.size()-1] >> __offset; } ////std::fill(this->_M_w.begin() + __limit + 1, this->_M_w.end(), //// static_cast<_WordT>(0)); } } template unsigned long __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ulong() const { size_t __n = sizeof(unsigned long) / sizeof(block_type); for (size_t __i = __n; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i]) __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ulong")); unsigned long __res = 0UL; for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i) __res += this->_M_w[__i] << (__i * _S_bits_per_block); return __res; } template unsigned long long __dynamic_bitset_base<_WordT, _Alloc>::_M_do_to_ullong() const { size_t __n = sizeof(unsigned long long) / sizeof(block_type); for (size_t __i = __n; __i < this->_M_w.size(); ++__i) if (this->_M_w[__i]) __throw_overflow_error(__N("__dynamic_bitset_base::_M_do_to_ullong")); unsigned long long __res = 0ULL; for (size_t __i = 0; __i < __n && __i < this->_M_w.size(); ++__i) __res += this->_M_w[__i] << (__i * _S_bits_per_block); return __res; } template size_t __dynamic_bitset_base<_WordT, _Alloc> ::_M_do_find_first(size_t __not_found) const { for (size_t __i = 0; __i < this->_M_w.size(); ++__i) { _WordT __thisword = this->_M_w[__i]; if (__thisword != static_cast<_WordT>(0)) return (__i * _S_bits_per_block + __builtin_ctzll(__thisword)); } // not found, so return an indication of failure. return __not_found; } template size_t __dynamic_bitset_base<_WordT, _Alloc> ::_M_do_find_next(size_t __prev, size_t __not_found) const { // make bound inclusive ++__prev; // check out of bounds if (__prev >= this->_M_w.size() * _S_bits_per_block) return __not_found; // search first word size_t __i = _S_whichword(__prev); _WordT __thisword = this->_M_w[__i]; // mask off bits below bound __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); if (__thisword != static_cast<_WordT>(0)) return (__i * _S_bits_per_block + __builtin_ctzll(__thisword)); // check subsequent words for (++__i; __i < this->_M_w.size(); ++__i) { __thisword = this->_M_w[__i]; if (__thisword != static_cast<_WordT>(0)) return (__i * _S_bits_per_block + __builtin_ctzll(__thisword)); } // not found, so return an indication of failure. return __not_found; } // end _M_do_find_next // Definitions of non-inline member functions. template template void dynamic_bitset<_WordT, _Alloc>:: _M_copy_from_ptr(const _CharT* __str, size_t __len, size_t __pos, size_t __n, _CharT __zero, _CharT __one) { reset(); const size_t __nbits = std::min(_M_Nb, std::min(__n, __len - __pos)); for (size_t __i = __nbits; __i > 0; --__i) { const _CharT __c = __str[__pos + __nbits - __i]; if (_Traits::eq(__c, __zero)) ; else if (_Traits::eq(__c, __one)) _M_unchecked_set(__i - 1); else __throw_invalid_argument(__N("dynamic_bitset::_M_copy_from_ptr")); } } /** * @brief Stream input operator for dynamic_bitset. * @ingroup dynamic_bitset * * Input will skip whitespace and only accept '0' and '1' characters. * The %dynamic_bitset will grow as necessary to hold the string of bits. */ template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, dynamic_bitset<_WordT, _Alloc>& __x) { typedef typename _Traits::char_type char_type; typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; std::basic_string<_CharT, _Traits> __tmp; __tmp.reserve(__x.size()); const char_type __zero = __is.widen('0'); const char_type __one = __is.widen('1'); typename __ios_base::iostate __state = __ios_base::goodbit; typename __istream_type::sentry __sentry(__is); if (__sentry) { __try { while (1) { static typename _Traits::int_type __eof = _Traits::eof(); typename _Traits::int_type __c1 = __is.rdbuf()->sbumpc(); if (_Traits::eq_int_type(__c1, __eof)) { __state |= __ios_base::eofbit; break; } else { const char_type __c2 = _Traits::to_char_type(__c1); if (_Traits::eq(__c2, __zero)) __tmp.push_back(__zero); else if (_Traits::eq(__c2, __one)) __tmp.push_back(__one); else if (_Traits:: eq_int_type(__is.rdbuf()->sputbackc(__c2), __eof)) { __state |= __ios_base::failbit; break; } else break; } } } __catch(__cxxabiv1::__forced_unwind&) { __is._M_setstate(__ios_base::badbit); __throw_exception_again; } __catch(...) { __is._M_setstate(__ios_base::badbit); } } __x.resize(__tmp.size()); if (__tmp.empty() && __x.size()) __state |= __ios_base::failbit; else __x._M_copy_from_string(__tmp, static_cast(0), __x.size(), __zero, __one); if (__state) __is.setstate(__state); return __is; } } // tr2 _GLIBCXX_END_NAMESPACE_VERSION } // std #endif /* _GLIBCXX_TR2_DYNAMIC_BITSET_TCC */ 8/utility000064400000030017152526447520006356 0ustar00// -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file include/utility * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_UTILITY #define _GLIBCXX_UTILITY 1 #pragma GCC system_header /** * @defgroup utilities Utilities * * Components deemed generally useful. Includes pair, tuple, * forward/move helpers, ratio, function object, metaprogramming and * type traits, time, date, and memory functions. */ #include #include #include #if __cplusplus >= 201103L #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Finds the size of a given tuple type. template struct tuple_size; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2313. tuple_size should always derive from integral_constant // 2770. tuple_size specialization is not SFINAE compatible template::type, typename = typename enable_if::value>::type, size_t = tuple_size<_Tp>::value> using __enable_if_has_tuple_size = _Tp; template struct tuple_size> : public tuple_size<_Tp> { }; template struct tuple_size> : public tuple_size<_Tp> { }; template struct tuple_size> : public tuple_size<_Tp> { }; /// Gives the type of the ith element of a given tuple type. template struct tuple_element; // Duplicate of C++14's tuple_element_t for internal use in C++11 mode template using __tuple_element_t = typename tuple_element<__i, _Tp>::type; template struct tuple_element<__i, const _Tp> { typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type; }; template struct tuple_element<__i, volatile _Tp> { typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type; }; template struct tuple_element<__i, const volatile _Tp> { typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type; }; #if __cplusplus > 201103L #define __cpp_lib_tuple_element_t 201402 template using tuple_element_t = typename tuple_element<__i, _Tp>::type; #endif // Various functions which give std::pair a tuple-like interface. /// Partial specialization for std::pair template struct __is_tuple_like_impl> : true_type { }; /// Partial specialization for std::pair template struct tuple_size> : public integral_constant { }; /// Partial specialization for std::pair template struct tuple_element<0, std::pair<_Tp1, _Tp2>> { typedef _Tp1 type; }; /// Partial specialization for std::pair template struct tuple_element<1, std::pair<_Tp1, _Tp2>> { typedef _Tp2 type; }; template struct __pair_get; template<> struct __pair_get<0> { template static constexpr _Tp1& __get(std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.first; } template static constexpr _Tp1&& __move_get(std::pair<_Tp1, _Tp2>&& __pair) noexcept { return std::forward<_Tp1>(__pair.first); } template static constexpr const _Tp1& __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.first; } template static constexpr const _Tp1&& __const_move_get(const std::pair<_Tp1, _Tp2>&& __pair) noexcept { return std::forward(__pair.first); } }; template<> struct __pair_get<1> { template static constexpr _Tp2& __get(std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.second; } template static constexpr _Tp2&& __move_get(std::pair<_Tp1, _Tp2>&& __pair) noexcept { return std::forward<_Tp2>(__pair.second); } template static constexpr const _Tp2& __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept { return __pair.second; } template static constexpr const _Tp2&& __const_move_get(const std::pair<_Tp1, _Tp2>&& __pair) noexcept { return std::forward(__pair.second); } }; template constexpr typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& get(std::pair<_Tp1, _Tp2>& __in) noexcept { return __pair_get<_Int>::__get(__in); } template constexpr typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type&& get(std::pair<_Tp1, _Tp2>&& __in) noexcept { return __pair_get<_Int>::__move_get(std::move(__in)); } template constexpr const typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& get(const std::pair<_Tp1, _Tp2>& __in) noexcept { return __pair_get<_Int>::__const_get(__in); } template constexpr const typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type&& get(const std::pair<_Tp1, _Tp2>&& __in) noexcept { return __pair_get<_Int>::__const_move_get(std::move(__in)); } #if __cplusplus > 201103L #define __cpp_lib_tuples_by_type 201304 template constexpr _Tp& get(pair<_Tp, _Up>& __p) noexcept { return __p.first; } template constexpr const _Tp& get(const pair<_Tp, _Up>& __p) noexcept { return __p.first; } template constexpr _Tp&& get(pair<_Tp, _Up>&& __p) noexcept { return std::move(__p.first); } template constexpr const _Tp&& get(const pair<_Tp, _Up>&& __p) noexcept { return std::move(__p.first); } template constexpr _Tp& get(pair<_Up, _Tp>& __p) noexcept { return __p.second; } template constexpr const _Tp& get(const pair<_Up, _Tp>& __p) noexcept { return __p.second; } template constexpr _Tp&& get(pair<_Up, _Tp>&& __p) noexcept { return std::move(__p.second); } template constexpr const _Tp&& get(const pair<_Up, _Tp>&& __p) noexcept { return std::move(__p.second); } #define __cpp_lib_exchange_function 201304 /// Assign @p __new_val to @p __obj and return its previous value. template inline _Tp exchange(_Tp& __obj, _Up&& __new_val) { return std::__exchange(__obj, std::forward<_Up>(__new_val)); } #endif // Stores a tuple of indices. Used by tuple and pair, and by bind() to // extract the elements in a tuple. template struct _Index_tuple { }; #ifdef __has_builtin # if __has_builtin(__make_integer_seq) # define _GLIBCXX_USE_MAKE_INTEGER_SEQ 1 # endif #endif // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. template struct _Build_index_tuple { #if _GLIBCXX_USE_MAKE_INTEGER_SEQ template using _IdxTuple = _Index_tuple<_Indices...>; using __type = __make_integer_seq<_IdxTuple, size_t, _Num>; #else using __type = _Index_tuple<__integer_pack(_Num)...>; #endif }; #if __cplusplus > 201103L #define __cpp_lib_integer_sequence 201304 /// Class template integer_sequence template struct integer_sequence { typedef _Tp value_type; static constexpr size_t size() noexcept { return sizeof...(_Idx); } }; /// Alias template make_integer_sequence template using make_integer_sequence #if _GLIBCXX_USE_MAKE_INTEGER_SEQ = __make_integer_seq; #else = integer_sequence<_Tp, __integer_pack(_Num)...>; #endif #undef _GLIBCXX_USE_MAKE_INTEGER_SEQ /// Alias template index_sequence template using index_sequence = integer_sequence; /// Alias template make_index_sequence template using make_index_sequence = make_integer_sequence; /// Alias template index_sequence_for template using index_sequence_for = make_index_sequence; #endif #if __cplusplus > 201402L struct in_place_t { explicit in_place_t() = default; }; inline constexpr in_place_t in_place{}; template struct in_place_type_t { explicit in_place_type_t() = default; }; template inline constexpr in_place_type_t<_Tp> in_place_type{}; template struct in_place_index_t { explicit in_place_index_t() = default; }; template inline constexpr in_place_index_t<_Idx> in_place_index{}; template struct __is_in_place_type_impl : false_type { }; template struct __is_in_place_type_impl> : true_type { }; template struct __is_in_place_type : public __is_in_place_type_impl<_Tp> { }; #define __cpp_lib_as_const 201510 template constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; } template void as_const(const _Tp&&) = delete; #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif #endif /* _GLIBCXX_UTILITY */ 8/string_view000064400000050467152526447520007226 0ustar00// Components for manipulating non-owning sequences of characters -*- C++ -*- // Copyright (C) 2013-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file string_view * This is a Standard C++ Library header. */ // // N3762 basic_string_view library // #ifndef _GLIBCXX_STRING_VIEW #define _GLIBCXX_STRING_VIEW 1 #pragma GCC system_header #if __cplusplus >= 201703L #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #define __cpp_lib_string_view 201603 /** * @class basic_string_view * @brief A non-owning reference to a string. * * @ingroup strings * @ingroup sequences * * @tparam _CharT Type of character * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * A basic_string_view looks like this: * * @code * _CharT* _M_str * size_t _M_len * @endcode */ template> class basic_string_view { public: // types using traits_type = _Traits; using value_type = _CharT; using pointer = const _CharT*; using const_pointer = const _CharT*; using reference = const _CharT&; using const_reference = const _CharT&; using const_iterator = const _CharT*; using iterator = const_iterator; using const_reverse_iterator = std::reverse_iterator; using reverse_iterator = const_reverse_iterator; using size_type = size_t; using difference_type = ptrdiff_t; static constexpr size_type npos = size_type(-1); // [string.view.cons], construct/copy constexpr basic_string_view() noexcept : _M_len{0}, _M_str{nullptr} { } constexpr basic_string_view(const basic_string_view&) noexcept = default; constexpr basic_string_view(const _CharT* __str) noexcept : _M_len{__str == nullptr ? 0 : traits_type::length(__str)}, _M_str{__str} { } constexpr basic_string_view(const _CharT* __str, size_type __len) noexcept : _M_len{__len}, _M_str{__str} { } constexpr basic_string_view& operator=(const basic_string_view&) noexcept = default; // [string.view.iterators], iterators constexpr const_iterator begin() const noexcept { return this->_M_str; } constexpr const_iterator end() const noexcept { return this->_M_str + this->_M_len; } constexpr const_iterator cbegin() const noexcept { return this->_M_str; } constexpr const_iterator cend() const noexcept { return this->_M_str + this->_M_len; } constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(this->end()); } constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(this->begin()); } constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(this->end()); } constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(this->begin()); } // [string.view.capacity], capacity constexpr size_type size() const noexcept { return this->_M_len; } constexpr size_type length() const noexcept { return _M_len; } constexpr size_type max_size() const noexcept { return (npos - sizeof(size_type) - sizeof(void*)) / sizeof(value_type) / 4; } [[nodiscard]] constexpr bool empty() const noexcept { return this->_M_len == 0; } // [string.view.access], element access constexpr const _CharT& operator[](size_type __pos) const noexcept { __glibcxx_assert(__pos < this->_M_len); return *(this->_M_str + __pos); } constexpr const _CharT& at(size_type __pos) const { if (__pos >= _M_len) __throw_out_of_range_fmt(__N("basic_string_view::at: __pos " "(which is %zu) >= this->size() " "(which is %zu)"), __pos, this->size()); return *(this->_M_str + __pos); } constexpr const _CharT& front() const noexcept { __glibcxx_assert(this->_M_len > 0); return *this->_M_str; } constexpr const _CharT& back() const noexcept { __glibcxx_assert(this->_M_len > 0); return *(this->_M_str + this->_M_len - 1); } constexpr const _CharT* data() const noexcept { return this->_M_str; } // [string.view.modifiers], modifiers: constexpr void remove_prefix(size_type __n) noexcept { __glibcxx_assert(this->_M_len >= __n); this->_M_str += __n; this->_M_len -= __n; } constexpr void remove_suffix(size_type __n) noexcept { this->_M_len -= __n; } constexpr void swap(basic_string_view& __sv) noexcept { auto __tmp = *this; *this = __sv; __sv = __tmp; } // [string.view.ops], string operations: size_type copy(_CharT* __str, size_type __n, size_type __pos = 0) const { __glibcxx_requires_string_len(__str, __n); __pos = _M_check(__pos, "basic_string_view::copy"); const size_type __rlen = std::min(__n, _M_len - __pos); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2777. basic_string_view::copy should use char_traits::copy traits_type::copy(__str, data() + __pos, __rlen); return __rlen; } constexpr basic_string_view substr(size_type __pos = 0, size_type __n = npos) const noexcept(false) { __pos = _M_check(__pos, "basic_string_view::substr"); const size_type __rlen = std::min(__n, _M_len - __pos); return basic_string_view{_M_str + __pos, __rlen}; } constexpr int compare(basic_string_view __str) const noexcept { const size_type __rlen = std::min(this->_M_len, __str._M_len); int __ret = traits_type::compare(this->_M_str, __str._M_str, __rlen); if (__ret == 0) __ret = _S_compare(this->_M_len, __str._M_len); return __ret; } constexpr int compare(size_type __pos1, size_type __n1, basic_string_view __str) const { return this->substr(__pos1, __n1).compare(__str); } constexpr int compare(size_type __pos1, size_type __n1, basic_string_view __str, size_type __pos2, size_type __n2) const { return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); } constexpr int compare(const _CharT* __str) const noexcept { return this->compare(basic_string_view{__str}); } constexpr int compare(size_type __pos1, size_type __n1, const _CharT* __str) const { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); } constexpr int compare(size_type __pos1, size_type __n1, const _CharT* __str, size_type __n2) const noexcept(false) { return this->substr(__pos1, __n1) .compare(basic_string_view(__str, __n2)); } constexpr size_type find(basic_string_view __str, size_type __pos = 0) const noexcept { return this->find(__str._M_str, __pos, __str._M_len); } constexpr size_type find(_CharT __c, size_type __pos = 0) const noexcept; constexpr size_type find(const _CharT* __str, size_type __pos, size_type __n) const noexcept; constexpr size_type find(const _CharT* __str, size_type __pos = 0) const noexcept { return this->find(__str, __pos, traits_type::length(__str)); } constexpr size_type rfind(basic_string_view __str, size_type __pos = npos) const noexcept { return this->rfind(__str._M_str, __pos, __str._M_len); } constexpr size_type rfind(_CharT __c, size_type __pos = npos) const noexcept; constexpr size_type rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept; constexpr size_type rfind(const _CharT* __str, size_type __pos = npos) const noexcept { return this->rfind(__str, __pos, traits_type::length(__str)); } constexpr size_type find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept { return this->find_first_of(__str._M_str, __pos, __str._M_len); } constexpr size_type find_first_of(_CharT __c, size_type __pos = 0) const noexcept { return this->find(__c, __pos); } constexpr size_type find_first_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept; constexpr size_type find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept { return this->find_first_of(__str, __pos, traits_type::length(__str)); } constexpr size_type find_last_of(basic_string_view __str, size_type __pos = npos) const noexcept { return this->find_last_of(__str._M_str, __pos, __str._M_len); } constexpr size_type find_last_of(_CharT __c, size_type __pos=npos) const noexcept { return this->rfind(__c, __pos); } constexpr size_type find_last_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept; constexpr size_type find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept { return this->find_last_of(__str, __pos, traits_type::length(__str)); } constexpr size_type find_first_not_of(basic_string_view __str, size_type __pos = 0) const noexcept { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); } constexpr size_type find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept; constexpr size_type find_first_not_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept; constexpr size_type find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept { return this->find_first_not_of(__str, __pos, traits_type::length(__str)); } constexpr size_type find_last_not_of(basic_string_view __str, size_type __pos = npos) const noexcept { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); } constexpr size_type find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept; constexpr size_type find_last_not_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept; constexpr size_type find_last_not_of(const _CharT* __str, size_type __pos = npos) const noexcept { return this->find_last_not_of(__str, __pos, traits_type::length(__str)); } constexpr size_type _M_check(size_type __pos, const char* __s) const noexcept(false) { if (__pos > this->size()) __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > " "this->size() (which is %zu)"), __s, __pos, this->size()); return __pos; } // NB: _M_limit doesn't check for a bad __pos value. constexpr size_type _M_limit(size_type __pos, size_type __off) const noexcept { const bool __testoff = __off < this->size() - __pos; return __testoff ? __off : this->size() - __pos; } private: static constexpr int _S_compare(size_type __n1, size_type __n2) noexcept { const difference_type __diff = __n1 - __n2; if (__diff > std::numeric_limits::max()) return std::numeric_limits::max(); if (__diff < std::numeric_limits::min()) return std::numeric_limits::min(); return static_cast(__diff); } size_t _M_len; const _CharT* _M_str; }; // [string.view.comparison], non-member basic_string_view comparison function namespace __detail { // Identity transform to create a non-deduced context, so that only one // argument participates in template argument deduction and the other // argument gets implicitly converted to the deduced type. See n3766.html. template using __idt = common_type_t<_Tp>; } template constexpr bool operator==(basic_string_view<_CharT, _Traits> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.size() == __y.size() && __x.compare(__y) == 0; } template constexpr bool operator==(basic_string_view<_CharT, _Traits> __x, __detail::__idt> __y) noexcept { return __x.size() == __y.size() && __x.compare(__y) == 0; } template constexpr bool operator==(__detail::__idt> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.size() == __y.size() && __x.compare(__y) == 0; } template constexpr bool operator!=(basic_string_view<_CharT, _Traits> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return !(__x == __y); } template constexpr bool operator!=(basic_string_view<_CharT, _Traits> __x, __detail::__idt> __y) noexcept { return !(__x == __y); } template constexpr bool operator!=(__detail::__idt> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return !(__x == __y); } template constexpr bool operator< (basic_string_view<_CharT, _Traits> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) < 0; } template constexpr bool operator< (basic_string_view<_CharT, _Traits> __x, __detail::__idt> __y) noexcept { return __x.compare(__y) < 0; } template constexpr bool operator< (__detail::__idt> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) < 0; } template constexpr bool operator> (basic_string_view<_CharT, _Traits> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) > 0; } template constexpr bool operator> (basic_string_view<_CharT, _Traits> __x, __detail::__idt> __y) noexcept { return __x.compare(__y) > 0; } template constexpr bool operator> (__detail::__idt> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) > 0; } template constexpr bool operator<=(basic_string_view<_CharT, _Traits> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) <= 0; } template constexpr bool operator<=(basic_string_view<_CharT, _Traits> __x, __detail::__idt> __y) noexcept { return __x.compare(__y) <= 0; } template constexpr bool operator<=(__detail::__idt> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) <= 0; } template constexpr bool operator>=(basic_string_view<_CharT, _Traits> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) >= 0; } template constexpr bool operator>=(basic_string_view<_CharT, _Traits> __x, __detail::__idt> __y) noexcept { return __x.compare(__y) >= 0; } template constexpr bool operator>=(__detail::__idt> __x, basic_string_view<_CharT, _Traits> __y) noexcept { return __x.compare(__y) >= 0; } // [string.view.io], Inserters and extractors template inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT,_Traits> __str) { return __ostream_insert(__os, __str.data(), __str.size()); } // basic_string_view typedef names using string_view = basic_string_view; #ifdef _GLIBCXX_USE_WCHAR_T using wstring_view = basic_string_view; #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 using u16string_view = basic_string_view; using u32string_view = basic_string_view; #endif // [string.view.hash], hash support: template struct hash; template<> struct hash : public __hash_base { size_t operator()(const string_view& __str) const noexcept { return std::_Hash_impl::hash(__str.data(), __str.length()); } }; template<> struct __is_fast_hash> : std::false_type { }; #ifdef _GLIBCXX_USE_WCHAR_T template<> struct hash : public __hash_base { size_t operator()(const wstring_view& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length() * sizeof(wchar_t)); } }; template<> struct __is_fast_hash> : std::false_type { }; #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 template<> struct hash : public __hash_base { size_t operator()(const u16string_view& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length() * sizeof(char16_t)); } }; template<> struct __is_fast_hash> : std::false_type { }; template<> struct hash : public __hash_base { size_t operator()(const u32string_view& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length() * sizeof(char32_t)); } }; template<> struct __is_fast_hash> : std::false_type { }; #endif inline namespace literals { inline namespace string_view_literals { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wliteral-suffix" inline constexpr basic_string_view operator""sv(const char* __str, size_t __len) noexcept { return basic_string_view{__str, __len}; } #ifdef _GLIBCXX_USE_WCHAR_T inline constexpr basic_string_view operator""sv(const wchar_t* __str, size_t __len) noexcept { return basic_string_view{__str, __len}; } #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 inline constexpr basic_string_view operator""sv(const char16_t* __str, size_t __len) noexcept { return basic_string_view{__str, __len}; } inline constexpr basic_string_view operator""sv(const char32_t* __str, size_t __len) noexcept { return basic_string_view{__str, __len}; } #endif #pragma GCC diagnostic pop } // namespace string_literals } // namespace literals _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #include #endif // __cplusplus <= 201402L #endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW 8/cstring000064400000006063152526447520006330 0ustar00// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file cstring * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c string.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 20.4.6 C library // #pragma GCC system_header #include #include #ifndef _GLIBCXX_CSTRING #define _GLIBCXX_CSTRING 1 // Get rid of those macros defined in in lieu of real functions. #undef memchr #undef memcmp #undef memcpy #undef memmove #undef memset #undef strcat #undef strchr #undef strcmp #undef strcoll #undef strcpy #undef strcspn #undef strerror #undef strlen #undef strncat #undef strncmp #undef strncpy #undef strpbrk #undef strrchr #undef strspn #undef strstr #undef strtok #undef strxfrm namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::memchr; using ::memcmp; using ::memcpy; using ::memmove; using ::memset; using ::strcat; using ::strcmp; using ::strcoll; using ::strcpy; using ::strcspn; using ::strerror; using ::strlen; using ::strncat; using ::strncmp; using ::strncpy; using ::strspn; using ::strtok; using ::strxfrm; using ::strchr; using ::strpbrk; using ::strrchr; using ::strstr; #ifndef __CORRECT_ISO_CPP_STRING_H_PROTO inline void* memchr(void* __s, int __c, size_t __n) { return __builtin_memchr(__s, __c, __n); } inline char* strchr(char* __s, int __n) { return __builtin_strchr(__s, __n); } inline char* strpbrk(char* __s1, const char* __s2) { return __builtin_strpbrk(__s1, __s2); } inline char* strrchr(char* __s, int __n) { return __builtin_strrchr(__s, __n); } inline char* strstr(char* __s1, const char* __s2) { return __builtin_strstr(__s1, __s2); } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/tuple000064400000165676152526447520006030 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/tuple * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_TUPLE #define _GLIBCXX_TUPLE 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup utilities * @{ */ template class tuple; template struct __is_empty_non_tuple : is_empty<_Tp> { }; // Using EBO for elements that are tuples causes ambiguous base errors. template struct __is_empty_non_tuple> : false_type { }; // Use the Empty Base-class Optimization for empty, non-final types. template using __empty_not_final = typename conditional<__is_final(_Tp), false_type, __is_empty_non_tuple<_Tp>>::type; template::value> struct _Head_base; template struct _Head_base<_Idx, _Head, true> : public _Head { constexpr _Head_base() : _Head() { } constexpr _Head_base(const _Head& __h) : _Head(__h) { } constexpr _Head_base(const _Head_base&) = default; constexpr _Head_base(_Head_base&&) = default; template constexpr _Head_base(_UHead&& __h) : _Head(std::forward<_UHead>(__h)) { } _Head_base(allocator_arg_t, __uses_alloc0) : _Head() { } template _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) : _Head(allocator_arg, *__a._M_a) { } template _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) : _Head(*__a._M_a) { } template _Head_base(__uses_alloc0, _UHead&& __uhead) : _Head(std::forward<_UHead>(__uhead)) { } template _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } template _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { } static constexpr _Head& _M_head(_Head_base& __b) noexcept { return __b; } static constexpr const _Head& _M_head(const _Head_base& __b) noexcept { return __b; } }; template struct _Head_base<_Idx, _Head, false> { constexpr _Head_base() : _M_head_impl() { } constexpr _Head_base(const _Head& __h) : _M_head_impl(__h) { } constexpr _Head_base(const _Head_base&) = default; constexpr _Head_base(_Head_base&&) = default; template constexpr _Head_base(_UHead&& __h) : _M_head_impl(std::forward<_UHead>(__h)) { } _Head_base(allocator_arg_t, __uses_alloc0) : _M_head_impl() { } template _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) : _M_head_impl(allocator_arg, *__a._M_a) { } template _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) : _M_head_impl(*__a._M_a) { } template _Head_base(__uses_alloc0, _UHead&& __uhead) : _M_head_impl(std::forward<_UHead>(__uhead)) { } template _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } template _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } static constexpr _Head& _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } static constexpr const _Head& _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } _Head _M_head_impl; }; /** * Contains the actual implementation of the @c tuple template, stored * as a recursive inheritance hierarchy from the first element (most * derived class) to the last (least derived class). The @c Idx * parameter gives the 0-based index of the element stored at this * point in the hierarchy; we use it to implement a constant-time * get() operation. */ template struct _Tuple_impl; /** * Recursive tuple implementation. Here we store the @c Head element * and derive from a @c Tuple_impl containing the remaining elements * (which contains the @c Tail). */ template struct _Tuple_impl<_Idx, _Head, _Tail...> : public _Tuple_impl<_Idx + 1, _Tail...>, private _Head_base<_Idx, _Head> { template friend class _Tuple_impl; typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; typedef _Head_base<_Idx, _Head> _Base; static constexpr _Head& _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } static constexpr const _Head& _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } static constexpr _Inherited& _M_tail(_Tuple_impl& __t) noexcept { return __t; } static constexpr const _Inherited& _M_tail(const _Tuple_impl& __t) noexcept { return __t; } constexpr _Tuple_impl() : _Inherited(), _Base() { } explicit constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail) : _Inherited(__tail...), _Base(__head) { } template::type> explicit constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail) : _Inherited(std::forward<_UTail>(__tail)...), _Base(std::forward<_UHead>(__head)) { } constexpr _Tuple_impl(const _Tuple_impl&) = default; constexpr _Tuple_impl(_Tuple_impl&& __in) noexcept(__and_, is_nothrow_move_constructible<_Inherited>>::value) : _Inherited(std::move(_M_tail(__in))), _Base(std::forward<_Head>(_M_head(__in))) { } template constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } template constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) : _Inherited(std::move (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), _Base(std::forward<_UHead> (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) : _Inherited(__tag, __a), _Base(__tag, __use_alloc<_Head>(__a)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Head& __head, const _Tail&... __tail) : _Inherited(__tag, __a, __tail...), _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } template::type> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _UHead&& __head, _UTail&&... __tail) : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...), _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), std::forward<_UHead>(__head)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl& __in) : _Inherited(__tag, __a, _M_tail(__in)), _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl&& __in) : _Inherited(__tag, __a, std::move(_M_tail(__in))), _Base(__use_alloc<_Head, _Alloc, _Head>(__a), std::forward<_Head>(_M_head(__in))) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl<_Idx, _UHead, _UTails...>& __in) : _Inherited(__tag, __a, _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)), _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a), _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) : _Inherited(__tag, __a, std::move (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), std::forward<_UHead> (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } _Tuple_impl& operator=(const _Tuple_impl& __in) { _M_head(*this) = _M_head(__in); _M_tail(*this) = _M_tail(__in); return *this; } _Tuple_impl& operator=(_Tuple_impl&& __in) noexcept(__and_, is_nothrow_move_assignable<_Inherited>>::value) { _M_head(*this) = std::forward<_Head>(_M_head(__in)); _M_tail(*this) = std::move(_M_tail(__in)); return *this; } template _Tuple_impl& operator=(const _Tuple_impl<_Idx, _UElements...>& __in) { _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in); return *this; } template _Tuple_impl& operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) { _M_head(*this) = std::forward<_UHead> (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); _M_tail(*this) = std::move (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)); return *this; } protected: void _M_swap(_Tuple_impl& __in) noexcept(__is_nothrow_swappable<_Head>::value && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) { using std::swap; swap(_M_head(*this), _M_head(__in)); _Inherited::_M_swap(_M_tail(__in)); } }; // Basis case of inheritance recursion. template struct _Tuple_impl<_Idx, _Head> : private _Head_base<_Idx, _Head> { template friend class _Tuple_impl; typedef _Head_base<_Idx, _Head> _Base; static constexpr _Head& _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } static constexpr const _Head& _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } constexpr _Tuple_impl() : _Base() { } explicit constexpr _Tuple_impl(const _Head& __head) : _Base(__head) { } template explicit constexpr _Tuple_impl(_UHead&& __head) : _Base(std::forward<_UHead>(__head)) { } constexpr _Tuple_impl(const _Tuple_impl&) = default; constexpr _Tuple_impl(_Tuple_impl&& __in) noexcept(is_nothrow_move_constructible<_Head>::value) : _Base(std::forward<_Head>(_M_head(__in))) { } template constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } template constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in) : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) : _Base(__tag, __use_alloc<_Head>(__a)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Head& __head) : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _UHead&& __head) : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), std::forward<_UHead>(__head)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl& __in) : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl&& __in) : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), std::forward<_Head>(_M_head(__in))) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl<_Idx, _UHead>& __in) : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a), _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } template _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl<_Idx, _UHead>&& __in) : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) { } _Tuple_impl& operator=(const _Tuple_impl& __in) { _M_head(*this) = _M_head(__in); return *this; } _Tuple_impl& operator=(_Tuple_impl&& __in) noexcept(is_nothrow_move_assignable<_Head>::value) { _M_head(*this) = std::forward<_Head>(_M_head(__in)); return *this; } template _Tuple_impl& operator=(const _Tuple_impl<_Idx, _UHead>& __in) { _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in); return *this; } template _Tuple_impl& operator=(_Tuple_impl<_Idx, _UHead>&& __in) { _M_head(*this) = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); return *this; } protected: void _M_swap(_Tuple_impl& __in) noexcept(__is_nothrow_swappable<_Head>::value) { using std::swap; swap(_M_head(*this), _M_head(__in)); } }; // Concept utility functions, reused in conditionally-explicit // constructors. template struct _TC { template static constexpr bool _ConstructibleTuple() { return __and_...>::value; } template static constexpr bool _ImplicitlyConvertibleTuple() { return __and_...>::value; } template static constexpr bool _MoveConstructibleTuple() { return __and_...>::value; } template static constexpr bool _ImplicitlyMoveConvertibleTuple() { return __and_...>::value; } template static constexpr bool _NonNestedTuple() { return __and_<__not_, typename remove_cv< typename remove_reference<_SrcTuple>::type >::type>>, __not_>, __not_> >::value; } template static constexpr bool _NotSameTuple() { return __not_, typename remove_const< typename remove_reference<_UElements...>::type >::type>>::value; } }; template struct _TC { template static constexpr bool _ConstructibleTuple() { return false; } template static constexpr bool _ImplicitlyConvertibleTuple() { return false; } template static constexpr bool _MoveConstructibleTuple() { return false; } template static constexpr bool _ImplicitlyMoveConvertibleTuple() { return false; } template static constexpr bool _NonNestedTuple() { return true; } template static constexpr bool _NotSameTuple() { return true; } }; /// Primary class template, tuple template class tuple : public _Tuple_impl<0, _Elements...> { typedef _Tuple_impl<0, _Elements...> _Inherited; // Used for constraining the default constructor so // that it becomes dependent on the constraints. template struct _TC2 { static constexpr bool _DefaultConstructibleTuple() { return __and_...>::value; } static constexpr bool _ImplicitlyDefaultConstructibleTuple() { return __and_<__is_implicitly_default_constructible<_Elements>...> ::value; } }; public: template:: _ImplicitlyDefaultConstructibleTuple(), bool>::type = true> constexpr tuple() : _Inherited() { } template:: _DefaultConstructibleTuple() && !_TC2<_Dummy>:: _ImplicitlyDefaultConstructibleTuple(), bool>::type = false> explicit constexpr tuple() : _Inherited() { } // Shortcut for the cases where constructors taking _Elements... // need to be constrained. template using _TCC = _TC::value, _Elements...>; template::template _ConstructibleTuple<_Elements...>() && _TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_Elements...>() && (sizeof...(_Elements) >= 1), bool>::type=true> constexpr tuple(const _Elements&... __elements) : _Inherited(__elements...) { } template::template _ConstructibleTuple<_Elements...>() && !_TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_Elements...>() && (sizeof...(_Elements) >= 1), bool>::type=false> explicit constexpr tuple(const _Elements&... __elements) : _Inherited(__elements...) { } // Shortcut for the cases where constructors taking _UElements... // need to be constrained. template using _TMC = _TC<(sizeof...(_Elements) == sizeof...(_UElements)) && (_TC<(sizeof...(_UElements)==1), _Elements...>:: template _NotSameTuple<_UElements...>()), _Elements...>; // Shortcut for the cases where constructors taking tuple<_UElements...> // need to be constrained. template using _TMCT = _TC<(sizeof...(_Elements) == sizeof...(_UElements)) && !is_same, tuple<_UElements...>>::value, _Elements...>; template::template _MoveConstructibleTuple<_UElements...>() && _TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && (sizeof...(_Elements) >= 1), bool>::type=true> constexpr tuple(_UElements&&... __elements) : _Inherited(std::forward<_UElements>(__elements)...) { } template::template _MoveConstructibleTuple<_UElements...>() && !_TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && (sizeof...(_Elements) >= 1), bool>::type=false> explicit constexpr tuple(_UElements&&... __elements) : _Inherited(std::forward<_UElements>(__elements)...) { } constexpr tuple(const tuple&) = default; constexpr tuple(tuple&&) = default; // Shortcut for the cases where constructors taking tuples // must avoid creating temporaries. template using _TNTC = _TC::value && sizeof...(_Elements) == 1, _Elements...>; template::template _ConstructibleTuple<_UElements...>() && _TMCT<_UElements...>::template _ImplicitlyConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&>(), bool>::type=true> constexpr tuple(const tuple<_UElements...>& __in) : _Inherited(static_cast&>(__in)) { } template::template _ConstructibleTuple<_UElements...>() && !_TMCT<_UElements...>::template _ImplicitlyConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&>(), bool>::type=false> explicit constexpr tuple(const tuple<_UElements...>& __in) : _Inherited(static_cast&>(__in)) { } template::template _MoveConstructibleTuple<_UElements...>() && _TMCT<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&&>(), bool>::type=true> constexpr tuple(tuple<_UElements...>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } template::template _MoveConstructibleTuple<_UElements...>() && !_TMCT<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&&>(), bool>::type=false> explicit constexpr tuple(tuple<_UElements...>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } // Allocator-extended constructors. template tuple(allocator_arg_t __tag, const _Alloc& __a) : _Inherited(__tag, __a) { } template::template _ConstructibleTuple<_Elements...>() && _TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_Elements...>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, const _Elements&... __elements) : _Inherited(__tag, __a, __elements...) { } template::template _ConstructibleTuple<_Elements...>() && !_TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_Elements...>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const _Elements&... __elements) : _Inherited(__tag, __a, __elements...) { } template::template _MoveConstructibleTuple<_UElements...>() && _TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, _UElements&&... __elements) : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) { } template::template _MoveConstructibleTuple<_UElements...>() && !_TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, _UElements&&... __elements) : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) { } template tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) : _Inherited(__tag, __a, static_cast(__in)) { } template tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } template::template _ConstructibleTuple<_UElements...>() && _TMCT<_UElements...>::template _ImplicitlyConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&&>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_UElements...>& __in) : _Inherited(__tag, __a, static_cast&>(__in)) { } template::template _ConstructibleTuple<_UElements...>() && !_TMCT<_UElements...>::template _ImplicitlyConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&&>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_UElements...>& __in) : _Inherited(__tag, __a, static_cast&>(__in)) { } template::template _MoveConstructibleTuple<_UElements...>() && _TMCT<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&&>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UElements...>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } template::template _MoveConstructibleTuple<_UElements...>() && !_TMCT<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple&&>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UElements...>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } tuple& operator=(const tuple& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } tuple& operator=(tuple&& __in) noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; } template typename enable_if::type operator=(const tuple<_UElements...>& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } template typename enable_if::type operator=(tuple<_UElements...>&& __in) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; } void swap(tuple& __in) noexcept(noexcept(__in._M_swap(__in))) { _Inherited::_M_swap(__in); } }; #if __cpp_deduction_guides >= 201606 template tuple(_UTypes...) -> tuple<_UTypes...>; template tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>; template tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>; template tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>; template tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>; #endif // Explicit specialization, zero-element tuple. template<> class tuple<> { public: void swap(tuple&) noexcept { /* no-op */ } // We need the default since we're going to define no-op // allocator constructors. tuple() = default; // No-op allocator constructors. template tuple(allocator_arg_t, const _Alloc&) { } template tuple(allocator_arg_t, const _Alloc&, const tuple&) { } }; /// Partial specialization, 2-element tuple. /// Includes construction and assignment from a pair. template class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> { typedef _Tuple_impl<0, _T1, _T2> _Inherited; public: template , __is_implicitly_default_constructible<_U2>> ::value, bool>::type = true> constexpr tuple() : _Inherited() { } template , is_default_constructible<_U2>, __not_< __and_<__is_implicitly_default_constructible<_U1>, __is_implicitly_default_constructible<_U2>>>> ::value, bool>::type = false> explicit constexpr tuple() : _Inherited() { } // Shortcut for the cases where constructors taking _T1, _T2 // need to be constrained. template using _TCC = _TC::value, _T1, _T2>; template::template _ConstructibleTuple<_T1, _T2>() && _TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_T1, _T2>(), bool>::type = true> constexpr tuple(const _T1& __a1, const _T2& __a2) : _Inherited(__a1, __a2) { } template::template _ConstructibleTuple<_T1, _T2>() && !_TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_T1, _T2>(), bool>::type = false> explicit constexpr tuple(const _T1& __a1, const _T2& __a2) : _Inherited(__a1, __a2) { } // Shortcut for the cases where constructors taking _U1, _U2 // need to be constrained. using _TMC = _TC; template() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>() && !is_same::type, allocator_arg_t>::value, bool>::type = true> constexpr tuple(_U1&& __a1, _U2&& __a2) : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } template() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>() && !is_same::type, allocator_arg_t>::value, bool>::type = false> explicit constexpr tuple(_U1&& __a1, _U2&& __a2) : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } constexpr tuple(const tuple&) = default; constexpr tuple(tuple&&) = default; template() && _TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = true> constexpr tuple(const tuple<_U1, _U2>& __in) : _Inherited(static_cast&>(__in)) { } template() && !_TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit constexpr tuple(const tuple<_U1, _U2>& __in) : _Inherited(static_cast&>(__in)) { } template() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> constexpr tuple(tuple<_U1, _U2>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } template() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit constexpr tuple(tuple<_U1, _U2>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } template() && _TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = true> constexpr tuple(const pair<_U1, _U2>& __in) : _Inherited(__in.first, __in.second) { } template() && !_TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit constexpr tuple(const pair<_U1, _U2>& __in) : _Inherited(__in.first, __in.second) { } template() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> constexpr tuple(pair<_U1, _U2>&& __in) : _Inherited(std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } template() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit constexpr tuple(pair<_U1, _U2>&& __in) : _Inherited(std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } // Allocator-extended constructors. template tuple(allocator_arg_t __tag, const _Alloc& __a) : _Inherited(__tag, __a) { } template::template _ConstructibleTuple<_T1, _T2>() && _TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_T1, _T2>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, const _T1& __a1, const _T2& __a2) : _Inherited(__tag, __a, __a1, __a2) { } template::template _ConstructibleTuple<_T1, _T2>() && !_TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_T1, _T2>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const _T1& __a1, const _T2& __a2) : _Inherited(__tag, __a, __a1, __a2) { } template() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) : _Inherited(__tag, __a, std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } template() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) : _Inherited(__tag, __a, std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } template tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) : _Inherited(__tag, __a, static_cast(__in)) { } template tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } template() && _TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_U1, _U2>& __in) : _Inherited(__tag, __a, static_cast&>(__in)) { } template() && !_TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_U1, _U2>& __in) : _Inherited(__tag, __a, static_cast&>(__in)) { } template() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } template() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } template() && _TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>& __in) : _Inherited(__tag, __a, __in.first, __in.second) { } template() && !_TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>& __in) : _Inherited(__tag, __a, __in.first, __in.second) { } template() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) : _Inherited(__tag, __a, std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } template() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) : _Inherited(__tag, __a, std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } tuple& operator=(const tuple& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } tuple& operator=(tuple&& __in) noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; } template tuple& operator=(const tuple<_U1, _U2>& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } template tuple& operator=(tuple<_U1, _U2>&& __in) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; } template tuple& operator=(const pair<_U1, _U2>& __in) { this->_M_head(*this) = __in.first; this->_M_tail(*this)._M_head(*this) = __in.second; return *this; } template tuple& operator=(pair<_U1, _U2>&& __in) { this->_M_head(*this) = std::forward<_U1>(__in.first); this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); return *this; } void swap(tuple& __in) noexcept(noexcept(__in._M_swap(__in))) { _Inherited::_M_swap(__in); } }; /// class tuple_size template struct tuple_size> : public integral_constant { }; #if __cplusplus > 201402L template inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; #endif /** * Recursive case for tuple_element: strip off the first element in * the tuple and retrieve the (i-1)th element of the remaining tuple. */ template struct tuple_element<__i, tuple<_Head, _Tail...> > : tuple_element<__i - 1, tuple<_Tail...> > { }; /** * Basis case for tuple_element: The first element is the one we're seeking. */ template struct tuple_element<0, tuple<_Head, _Tail...> > { typedef _Head type; }; /** * Error case for tuple_element: invalid index. */ template struct tuple_element<__i, tuple<>> { static_assert(__i < tuple_size>::value, "tuple index is in range"); }; template constexpr _Head& __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } template constexpr const _Head& __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } /// Return a reference to the ith element of a tuple. template constexpr __tuple_element_t<__i, tuple<_Elements...>>& get(tuple<_Elements...>& __t) noexcept { return std::__get_helper<__i>(__t); } /// Return a const reference to the ith element of a const tuple. template constexpr const __tuple_element_t<__i, tuple<_Elements...>>& get(const tuple<_Elements...>& __t) noexcept { return std::__get_helper<__i>(__t); } /// Return an rvalue reference to the ith element of a tuple rvalue. template constexpr __tuple_element_t<__i, tuple<_Elements...>>&& get(tuple<_Elements...>&& __t) noexcept { typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; return std::forward<__element_type&&>(std::get<__i>(__t)); } /// Return a const rvalue reference to the ith element of a const tuple rvalue. template constexpr const __tuple_element_t<__i, tuple<_Elements...>>&& get(const tuple<_Elements...>&& __t) noexcept { typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; return std::forward(std::get<__i>(__t)); } #if __cplusplus > 201103L #define __cpp_lib_tuples_by_type 201304 template constexpr _Head& __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } template constexpr const _Head& __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } /// Return a reference to the unique element of type _Tp of a tuple. template constexpr _Tp& get(tuple<_Types...>& __t) noexcept { return std::__get_helper2<_Tp>(__t); } /// Return a reference to the unique element of type _Tp of a tuple rvalue. template constexpr _Tp&& get(tuple<_Types...>&& __t) noexcept { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); } /// Return a const reference to the unique element of type _Tp of a tuple. template constexpr const _Tp& get(const tuple<_Types...>& __t) noexcept { return std::__get_helper2<_Tp>(__t); } /// Return a const reference to the unique element of type _Tp of /// a const tuple rvalue. template constexpr const _Tp&& get(const tuple<_Types...>&& __t) noexcept { return std::forward(std::__get_helper2<_Tp>(__t)); } #endif // This class performs the comparison operations on tuples template struct __tuple_compare { static constexpr bool __eq(const _Tp& __t, const _Up& __u) { return bool(std::get<__i>(__t) == std::get<__i>(__u)) && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); } static constexpr bool __less(const _Tp& __t, const _Up& __u) { return bool(std::get<__i>(__t) < std::get<__i>(__u)) || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); } }; template struct __tuple_compare<_Tp, _Up, __size, __size> { static constexpr bool __eq(const _Tp&, const _Up&) { return true; } static constexpr bool __less(const _Tp&, const _Up&) { return false; } }; template constexpr bool operator==(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { static_assert(sizeof...(_TElements) == sizeof...(_UElements), "tuple objects can only be compared if they have equal sizes."); using __compare = __tuple_compare, tuple<_UElements...>, 0, sizeof...(_TElements)>; return __compare::__eq(__t, __u); } template constexpr bool operator<(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { static_assert(sizeof...(_TElements) == sizeof...(_UElements), "tuple objects can only be compared if they have equal sizes."); using __compare = __tuple_compare, tuple<_UElements...>, 0, sizeof...(_TElements)>; return __compare::__less(__t, __u); } template constexpr bool operator!=(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { return !(__t == __u); } template constexpr bool operator>(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { return __u < __t; } template constexpr bool operator<=(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { return !(__u < __t); } template constexpr bool operator>=(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { return !(__t < __u); } // NB: DR 705. template constexpr tuple::__type...> make_tuple(_Elements&&... __args) { typedef tuple::__type...> __result_type; return __result_type(std::forward<_Elements>(__args)...); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2275. Why is forward_as_tuple not constexpr? template constexpr tuple<_Elements&&...> forward_as_tuple(_Elements&&... __args) noexcept { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } template struct __make_tuple_impl; template struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> : __make_tuple_impl<_Idx + 1, tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, _Tuple, _Nm> { }; template struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> { typedef tuple<_Tp...> __type; }; template struct __do_make_tuple : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value> { }; // Returns the std::tuple equivalent of a tuple-like type. template struct __make_tuple : public __do_make_tuple::type>::type> { }; // Combines several std::tuple's into a single one. template struct __combine_tuples; template<> struct __combine_tuples<> { typedef tuple<> __type; }; template struct __combine_tuples> { typedef tuple<_Ts...> __type; }; template struct __combine_tuples, tuple<_T2s...>, _Rem...> { typedef typename __combine_tuples, _Rem...>::__type __type; }; // Computes the result type of tuple_cat given a set of tuple-like types. template struct __tuple_cat_result { typedef typename __combine_tuples ::__type...>::__type __type; }; // Helper to determine the index set for the first tuple-like // type of a given set. template struct __make_1st_indices; template<> struct __make_1st_indices<> { typedef std::_Index_tuple<> __type; }; template struct __make_1st_indices<_Tp, _Tpls...> { typedef typename std::_Build_index_tuple::type>::value>::__type __type; }; // Performs the actual concatenation by step-wise expanding tuple-like // objects into the elements, which are finally forwarded into the // result tuple. template struct __tuple_concater; template struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> { template static constexpr _Ret _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) { typedef typename __make_1st_indices<_Tpls...>::__type __idx; typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; return __next::_S_do(std::forward<_Tpls>(__tps)..., std::forward<_Us>(__us)..., std::get<_Is>(std::forward<_Tp>(__tp))...); } }; template struct __tuple_concater<_Ret, std::_Index_tuple<>> { template static constexpr _Ret _S_do(_Us&&... __us) { return _Ret(std::forward<_Us>(__us)...); } }; /// tuple_cat template...>::value>::type> constexpr auto tuple_cat(_Tpls&&... __tpls) -> typename __tuple_cat_result<_Tpls...>::__type { typedef typename __tuple_cat_result<_Tpls...>::__type __ret; typedef typename __make_1st_indices<_Tpls...>::__type __idx; typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; return __concater::_S_do(std::forward<_Tpls>(__tpls)...); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2301. Why is tie not constexpr? /// tie template constexpr tuple<_Elements&...> tie(_Elements&... __args) noexcept { return tuple<_Elements&...>(__args...); } /// swap template inline #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 // Constrained free swap overload, see p0185r1 typename enable_if<__and_<__is_swappable<_Elements>...>::value >::type #else void #endif swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 template typename enable_if...>::value>::type swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete; #endif // A class (and instance) which can be used in 'tie' when an element // of a tuple is not required. // _GLIBCXX14_CONSTEXPR // 2933. PR for LWG 2773 could be clearer struct _Swallow_assign { template _GLIBCXX14_CONSTEXPR const _Swallow_assign& operator=(const _Tp&) const { return *this; } }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2773. Making std::ignore constexpr _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{}; /// Partial specialization for tuples template struct uses_allocator, _Alloc> : true_type { }; // See stl_pair.h... template template inline pair<_T1, _T2>:: pair(piecewise_construct_t, tuple<_Args1...> __first, tuple<_Args2...> __second) : pair(__first, __second, typename _Build_index_tuple::__type(), typename _Build_index_tuple::__type()) { } template template inline pair<_T1, _T2>:: pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) { } #if __cplusplus > 201402L # define __cpp_lib_apply 201603 template constexpr decltype(auto) __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>) { return std::__invoke(std::forward<_Fn>(__f), std::get<_Idx>(std::forward<_Tuple>(__t))...); } template constexpr decltype(auto) apply(_Fn&& __f, _Tuple&& __t) { using _Indices = make_index_sequence>>; return std::__apply_impl(std::forward<_Fn>(__f), std::forward<_Tuple>(__t), _Indices{}); } #define __cpp_lib_make_from_tuple 201606 template constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>) { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); } template constexpr _Tp make_from_tuple(_Tuple&& __t) { return __make_from_tuple_impl<_Tp>( std::forward<_Tuple>(__t), make_index_sequence>>{}); } #endif // C++17 /// @} _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_TUPLE 8/optional000064400000125673152526447520006515 0ustar00// -*- C++ -*- // Copyright (C) 2013-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/optional * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_OPTIONAL #define _GLIBCXX_OPTIONAL 1 #pragma GCC system_header #if __cplusplus >= 201703L #include #include #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup utilities * @{ */ #define __cpp_lib_optional 201606L template class optional; /// Tag type to disengage optional objects. struct nullopt_t { // Do not user-declare default constructor at all for // optional_value = {} syntax to work. // nullopt_t() = delete; // Used for constructing nullopt. enum class _Construct { _Token }; // Must be constexpr for nullopt_t to be literal. explicit constexpr nullopt_t(_Construct) { } }; /// Tag to disengage optional objects. inline constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token }; /** * @brief Exception class thrown when a disengaged optional object is * dereferenced. * @ingroup exceptions */ class bad_optional_access : public exception { public: bad_optional_access() { } virtual const char* what() const noexcept override { return "bad optional access"; } virtual ~bad_optional_access() noexcept = default; }; void __throw_bad_optional_access() __attribute__((__noreturn__)); // XXX Does not belong here. inline void __throw_bad_optional_access() { _GLIBCXX_THROW_OR_ABORT(bad_optional_access()); } // Payload for optionals with non-trivial destructor. template , bool /*_HasTrivialCopy */ = is_trivially_copy_assignable_v<_Tp> && is_trivially_copy_constructible_v<_Tp>, bool /*_HasTrivialMove */ = is_trivially_move_assignable_v<_Tp> && is_trivially_move_constructible_v<_Tp>> struct _Optional_payload { constexpr _Optional_payload() noexcept : _M_empty() { } template constexpr _Optional_payload(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } template constexpr _Optional_payload(std::initializer_list<_Up> __il, _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), _M_engaged(true) { } constexpr _Optional_payload(bool __engaged, const _Optional_payload& __other) : _Optional_payload(__other) { } constexpr _Optional_payload(bool __engaged, _Optional_payload&& __other) : _Optional_payload(std::move(__other)) { } constexpr _Optional_payload(const _Optional_payload& __other) { if (__other._M_engaged) this->_M_construct(__other._M_payload); } constexpr _Optional_payload(_Optional_payload&& __other) { if (__other._M_engaged) this->_M_construct(std::move(__other._M_payload)); } constexpr _Optional_payload& operator=(const _Optional_payload& __other) { if (this->_M_engaged && __other._M_engaged) this->_M_get() = __other._M_get(); else { if (__other._M_engaged) this->_M_construct(__other._M_get()); else this->_M_reset(); } return *this; } constexpr _Optional_payload& operator=(_Optional_payload&& __other) noexcept(__and_, is_nothrow_move_assignable<_Tp>>()) { if (this->_M_engaged && __other._M_engaged) this->_M_get() = std::move(__other._M_get()); else { if (__other._M_engaged) this->_M_construct(std::move(__other._M_get())); else this->_M_reset(); } return *this; } using _Stored_type = remove_const_t<_Tp>; struct _Empty_byte { }; union { _Empty_byte _M_empty; _Stored_type _M_payload; }; bool _M_engaged = false; ~_Optional_payload() { if (_M_engaged) _M_payload.~_Stored_type(); } template void _M_construct(_Args&&... __args) noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) { ::new ((void *) std::__addressof(this->_M_payload)) _Stored_type(std::forward<_Args>(__args)...); this->_M_engaged = true; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { return this->_M_payload; } constexpr const _Tp& _M_get() const noexcept { return this->_M_payload; } // _M_reset is a 'safe' operation with no precondition. constexpr void _M_reset() noexcept { if (this->_M_engaged) { this->_M_engaged = false; this->_M_payload.~_Stored_type(); } } }; // Payload for potentially-constexpr optionals. template struct _Optional_payload<_Tp, true, true, true> { constexpr _Optional_payload() noexcept : _M_empty(), _M_engaged(false) { } template constexpr _Optional_payload(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } template constexpr _Optional_payload(std::initializer_list<_Up> __il, _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), _M_engaged(true) { } constexpr _Optional_payload(bool __engaged, const _Optional_payload& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(__other._M_get()); } constexpr _Optional_payload(bool __engaged, _Optional_payload&& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(std::move(__other._M_get())); } using _Stored_type = remove_const_t<_Tp>; struct _Empty_byte { }; union { _Empty_byte _M_empty; _Stored_type _M_payload; }; bool _M_engaged; // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { return this->_M_payload; } constexpr const _Tp& _M_get() const noexcept { return this->_M_payload; } }; // Payload for optionals with non-trivial copy assignment. template struct _Optional_payload<_Tp, true, false, true> { constexpr _Optional_payload() noexcept : _M_empty(), _M_engaged(false) { } template constexpr _Optional_payload(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } template constexpr _Optional_payload(std::initializer_list<_Up> __il, _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), _M_engaged(true) { } constexpr _Optional_payload(bool __engaged, const _Optional_payload& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(__other._M_get()); } constexpr _Optional_payload(bool __engaged, _Optional_payload&& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(std::move(__other._M_get())); } _Optional_payload(const _Optional_payload&) = default; _Optional_payload(_Optional_payload&&) = default; constexpr _Optional_payload& operator=(const _Optional_payload& __other) { if (this->_M_engaged && __other._M_engaged) this->_M_get() = __other._M_get(); else { if (__other._M_engaged) this->_M_construct(__other._M_get()); else this->_M_reset(); } return *this; } _Optional_payload& operator=(_Optional_payload&& __other) = default; using _Stored_type = remove_const_t<_Tp>; struct _Empty_byte { }; union { _Empty_byte _M_empty; _Stored_type _M_payload; }; bool _M_engaged; template void _M_construct(_Args&&... __args) noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) { ::new ((void *) std::__addressof(this->_M_payload)) _Stored_type(std::forward<_Args>(__args)...); this->_M_engaged = true; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { return this->_M_payload; } constexpr const _Tp& _M_get() const noexcept { return this->_M_payload; } // _M_reset is a 'safe' operation with no precondition. constexpr void _M_reset() noexcept { if (this->_M_engaged) { this->_M_engaged = false; this->_M_payload.~_Stored_type(); } } }; // Payload for optionals with non-trivial move assignment. template struct _Optional_payload<_Tp, true, true, false> { constexpr _Optional_payload() noexcept : _M_empty(), _M_engaged(false) { } template constexpr _Optional_payload(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } template constexpr _Optional_payload(std::initializer_list<_Up> __il, _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), _M_engaged(true) { } constexpr _Optional_payload(bool __engaged, const _Optional_payload& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(__other._M_get()); } constexpr _Optional_payload(bool __engaged, _Optional_payload&& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(std::move(__other._M_get())); } _Optional_payload(const _Optional_payload&) = default; _Optional_payload(_Optional_payload&&) = default; _Optional_payload& operator=(const _Optional_payload& __other) = default; constexpr _Optional_payload& operator=(_Optional_payload&& __other) noexcept(__and_, is_nothrow_move_assignable<_Tp>>()) { if (this->_M_engaged && __other._M_engaged) this->_M_get() = std::move(__other._M_get()); else { if (__other._M_engaged) this->_M_construct(std::move(__other._M_get())); else this->_M_reset(); } return *this; } using _Stored_type = remove_const_t<_Tp>; struct _Empty_byte { }; union { _Empty_byte _M_empty; _Stored_type _M_payload; }; bool _M_engaged; template void _M_construct(_Args&&... __args) noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) { ::new ((void *) std::__addressof(this->_M_payload)) _Stored_type(std::forward<_Args>(__args)...); this->_M_engaged = true; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { return this->_M_payload; } constexpr const _Tp& _M_get() const noexcept { return this->_M_payload; } // _M_reset is a 'safe' operation with no precondition. constexpr void _M_reset() noexcept { if (this->_M_engaged) { this->_M_engaged = false; this->_M_payload.~_Stored_type(); } } }; // Payload for optionals with non-trivial copy and move assignment. template struct _Optional_payload<_Tp, true, false, false> { constexpr _Optional_payload() noexcept : _M_empty(), _M_engaged(false) {} template constexpr _Optional_payload(in_place_t, _Args&&... __args) : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } template constexpr _Optional_payload(std::initializer_list<_Up> __il, _Args&&... __args) : _M_payload(__il, std::forward<_Args>(__args)...), _M_engaged(true) { } constexpr _Optional_payload(bool __engaged, const _Optional_payload& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(__other._M_get()); } constexpr _Optional_payload(bool __engaged, _Optional_payload&& __other) : _M_engaged(__engaged) { if (__engaged) _M_construct(std::move(__other._M_get())); } _Optional_payload(const _Optional_payload&) = default; _Optional_payload(_Optional_payload&&) = default; constexpr _Optional_payload& operator=(const _Optional_payload& __other) { if (this->_M_engaged && __other._M_engaged) this->_M_get() = __other._M_get(); else { if (__other._M_engaged) this->_M_construct(__other._M_get()); else this->_M_reset(); } return *this; } constexpr _Optional_payload& operator=(_Optional_payload&& __other) noexcept(__and_, is_nothrow_move_assignable<_Tp>>()) { if (this->_M_engaged && __other._M_engaged) this->_M_get() = std::move(__other._M_get()); else { if (__other._M_engaged) this->_M_construct(std::move(__other._M_get())); else this->_M_reset(); } return *this; } using _Stored_type = remove_const_t<_Tp>; struct _Empty_byte { }; union { _Empty_byte _M_empty; _Stored_type _M_payload; }; bool _M_engaged; template void _M_construct(_Args&&... __args) noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) { ::new ((void *) std::__addressof(this->_M_payload)) _Stored_type(std::forward<_Args>(__args)...); this->_M_engaged = true; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { return this->_M_payload; } constexpr const _Tp& _M_get() const noexcept { return this->_M_payload; } // _M_reset is a 'safe' operation with no precondition. constexpr void _M_reset() noexcept { if (this->_M_engaged) { this->_M_engaged = false; this->_M_payload.~_Stored_type(); } } }; template class _Optional_base_impl { protected: using _Stored_type = remove_const_t<_Tp>; // The _M_construct operation has !_M_engaged as a precondition // while _M_destruct has _M_engaged as a precondition. template void _M_construct(_Args&&... __args) noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) { ::new (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload)) _Stored_type(std::forward<_Args>(__args)...); static_cast<_Dp*>(this)->_M_payload._M_engaged = true; } void _M_destruct() noexcept { static_cast<_Dp*>(this)->_M_payload._M_engaged = false; static_cast<_Dp*>(this)->_M_payload._M_payload.~_Stored_type(); } // _M_reset is a 'safe' operation with no precondition. constexpr void _M_reset() noexcept { if (static_cast<_Dp*>(this)->_M_payload._M_engaged) static_cast<_Dp*>(this)->_M_destruct(); } }; /** * @brief Class template that takes care of copy/move constructors of optional * * Such a separate base class template is necessary in order to * conditionally make copy/move constructors trivial. * @see optional, _Enable_special_members */ template, bool = is_trivially_move_constructible_v<_Tp>> class _Optional_base // protected inheritance because optional needs to reach that base too : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>> { friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>; public: // Constructors for disengaged optionals. constexpr _Optional_base() = default; // Constructors for engaged optionals. template, bool> = false> constexpr explicit _Optional_base(in_place_t, _Args&&... __args) : _M_payload(in_place, std::forward<_Args>(__args)...) { } template&, _Args&&...>, bool> = false> constexpr explicit _Optional_base(in_place_t, initializer_list<_Up> __il, _Args&&... __args) : _M_payload(in_place, __il, std::forward<_Args>(__args)...) { } // Copy and move constructors. constexpr _Optional_base(const _Optional_base& __other) : _M_payload(__other._M_payload._M_engaged, __other._M_payload) { } constexpr _Optional_base(_Optional_base&& __other) noexcept(is_nothrow_move_constructible<_Tp>()) : _M_payload(__other._M_payload._M_engaged, std::move(__other._M_payload)) { } // Assignment operators. _Optional_base& operator=(const _Optional_base&) = default; _Optional_base& operator=(_Optional_base&&) = default; protected: constexpr bool _M_is_engaged() const noexcept { return this->_M_payload._M_engaged; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } constexpr const _Tp& _M_get() const noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } private: _Optional_payload<_Tp> _M_payload; }; template class _Optional_base<_Tp, false, true> : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>> { friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>; public: // Constructors for disengaged optionals. constexpr _Optional_base() = default; // Constructors for engaged optionals. template, bool> = false> constexpr explicit _Optional_base(in_place_t, _Args&&... __args) : _M_payload(in_place, std::forward<_Args>(__args)...) { } template&, _Args&&...>, bool> = false> constexpr explicit _Optional_base(in_place_t, initializer_list<_Up> __il, _Args&&... __args) : _M_payload(in_place, __il, std::forward<_Args>(__args)...) { } // Copy and move constructors. constexpr _Optional_base(const _Optional_base& __other) : _M_payload(__other._M_payload._M_engaged, __other._M_payload) { } constexpr _Optional_base(_Optional_base&& __other) = default; // Assignment operators. _Optional_base& operator=(const _Optional_base&) = default; _Optional_base& operator=(_Optional_base&&) = default; protected: constexpr bool _M_is_engaged() const noexcept { return this->_M_payload._M_engaged; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } constexpr const _Tp& _M_get() const noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } private: _Optional_payload<_Tp> _M_payload; }; template class _Optional_base<_Tp, true, false> : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>> { friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>; public: // Constructors for disengaged optionals. constexpr _Optional_base() = default; // Constructors for engaged optionals. template, bool> = false> constexpr explicit _Optional_base(in_place_t, _Args&&... __args) : _M_payload(in_place, std::forward<_Args>(__args)...) { } template&, _Args&&...>, bool> = false> constexpr explicit _Optional_base(in_place_t, initializer_list<_Up> __il, _Args&&... __args) : _M_payload(in_place, __il, std::forward<_Args>(__args)...) { } // Copy and move constructors. constexpr _Optional_base(const _Optional_base& __other) = default; constexpr _Optional_base(_Optional_base&& __other) noexcept(is_nothrow_move_constructible<_Tp>()) : _M_payload(__other._M_payload._M_engaged, std::move(__other._M_payload)) { } // Assignment operators. _Optional_base& operator=(const _Optional_base&) = default; _Optional_base& operator=(_Optional_base&&) = default; protected: constexpr bool _M_is_engaged() const noexcept { return this->_M_payload._M_engaged; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } constexpr const _Tp& _M_get() const noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } private: _Optional_payload<_Tp> _M_payload; }; template class _Optional_base<_Tp, true, true> : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>> { friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>; public: // Constructors for disengaged optionals. constexpr _Optional_base() = default; // Constructors for engaged optionals. template, bool> = false> constexpr explicit _Optional_base(in_place_t, _Args&&... __args) : _M_payload(in_place, std::forward<_Args>(__args)...) { } template&, _Args&&...>, bool> = false> constexpr explicit _Optional_base(in_place_t, initializer_list<_Up> __il, _Args&&... __args) : _M_payload(in_place, __il, std::forward<_Args>(__args)...) { } // Copy and move constructors. constexpr _Optional_base(const _Optional_base& __other) = default; constexpr _Optional_base(_Optional_base&& __other) = default; // Assignment operators. _Optional_base& operator=(const _Optional_base&) = default; _Optional_base& operator=(_Optional_base&&) = default; protected: constexpr bool _M_is_engaged() const noexcept { return this->_M_payload._M_engaged; } // The _M_get operations have _M_engaged as a precondition. constexpr _Tp& _M_get() noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } constexpr const _Tp& _M_get() const noexcept { __glibcxx_assert(this->_M_is_engaged()); return this->_M_payload._M_payload; } private: _Optional_payload<_Tp> _M_payload; }; template class optional; template using __converts_from_optional = __or_&>, is_constructible<_Tp, optional<_Up>&>, is_constructible<_Tp, const optional<_Up>&&>, is_constructible<_Tp, optional<_Up>&&>, is_convertible&, _Tp>, is_convertible&, _Tp>, is_convertible&&, _Tp>, is_convertible&&, _Tp>>; template using __assigns_from_optional = __or_&>, is_assignable<_Tp&, optional<_Up>&>, is_assignable<_Tp&, const optional<_Up>&&>, is_assignable<_Tp&, optional<_Up>&&>>; /** * @brief Class template for optional values. */ template class optional : private _Optional_base<_Tp>, private _Enable_copy_move< // Copy constructor. is_copy_constructible<_Tp>::value, // Copy assignment. __and_, is_copy_assignable<_Tp>>::value, // Move constructor. is_move_constructible<_Tp>::value, // Move assignment. __and_, is_move_assignable<_Tp>>::value, // Unique tag type. optional<_Tp>> { static_assert(!is_same_v, nullopt_t>); static_assert(!is_same_v, in_place_t>); static_assert(!is_reference_v<_Tp>); private: using _Base = _Optional_base<_Tp>; public: using value_type = _Tp; constexpr optional() = default; constexpr optional(nullopt_t) noexcept { } // Converting constructors for engaged optionals. template , decay_t<_Up>>>, __not_>>, is_constructible<_Tp, _Up&&>, is_convertible<_Up&&, _Tp> >::value, bool> = true> constexpr optional(_Up&& __t) : _Base(std::in_place, std::forward<_Up>(__t)) { } template , decay_t<_Up>>>, __not_>>, is_constructible<_Tp, _Up&&>, __not_> >::value, bool> = false> explicit constexpr optional(_Up&& __t) : _Base(std::in_place, std::forward<_Up>(__t)) { } template >, is_constructible<_Tp, const _Up&>, is_convertible, __not_<__converts_from_optional<_Tp, _Up>> >::value, bool> = true> constexpr optional(const optional<_Up>& __t) { if (__t) emplace(*__t); } template >, is_constructible<_Tp, const _Up&>, __not_>, __not_<__converts_from_optional<_Tp, _Up>> >::value, bool> = false> explicit constexpr optional(const optional<_Up>& __t) { if (__t) emplace(*__t); } template >, is_constructible<_Tp, _Up&&>, is_convertible<_Up&&, _Tp>, __not_<__converts_from_optional<_Tp, _Up>> >::value, bool> = true> constexpr optional(optional<_Up>&& __t) { if (__t) emplace(std::move(*__t)); } template >, is_constructible<_Tp, _Up&&>, __not_>, __not_<__converts_from_optional<_Tp, _Up>> >::value, bool> = false> explicit constexpr optional(optional<_Up>&& __t) { if (__t) emplace(std::move(*__t)); } template, bool> = false> explicit constexpr optional(in_place_t, _Args&&... __args) : _Base(std::in_place, std::forward<_Args>(__args)...) { } template&, _Args&&...>, bool> = false> explicit constexpr optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { } // Assignment operators. optional& operator=(nullopt_t) noexcept { this->_M_reset(); return *this; } template enable_if_t<__and_< __not_, decay_t<_Up>>>, is_constructible<_Tp, _Up>, __not_<__and_, is_same<_Tp, decay_t<_Up>>>>, is_assignable<_Tp&, _Up>>::value, optional&> operator=(_Up&& __u) { if (this->_M_is_engaged()) this->_M_get() = std::forward<_Up>(__u); else this->_M_construct(std::forward<_Up>(__u)); return *this; } template enable_if_t<__and_< __not_>, is_constructible<_Tp, const _Up&>, is_assignable<_Tp&, _Up>, __not_<__converts_from_optional<_Tp, _Up>>, __not_<__assigns_from_optional<_Tp, _Up>> >::value, optional&> operator=(const optional<_Up>& __u) { if (__u) { if (this->_M_is_engaged()) this->_M_get() = *__u; else this->_M_construct(*__u); } else { this->_M_reset(); } return *this; } template enable_if_t<__and_< __not_>, is_constructible<_Tp, _Up>, is_assignable<_Tp&, _Up>, __not_<__converts_from_optional<_Tp, _Up>>, __not_<__assigns_from_optional<_Tp, _Up>> >::value, optional&> operator=(optional<_Up>&& __u) { if (__u) { if (this->_M_is_engaged()) this->_M_get() = std::move(*__u); else this->_M_construct(std::move(*__u)); } else { this->_M_reset(); } return *this; } template enable_if_t::value, _Tp&> emplace(_Args&&... __args) { this->_M_reset(); this->_M_construct(std::forward<_Args>(__args)...); return this->_M_get(); } template enable_if_t&, _Args&&...>::value, _Tp&> emplace(initializer_list<_Up> __il, _Args&&... __args) { this->_M_reset(); this->_M_construct(__il, std::forward<_Args>(__args)...); return this->_M_get(); } // Destructor is implicit, implemented in _Optional_base. // Swap. void swap(optional& __other) noexcept(is_nothrow_move_constructible<_Tp>() && is_nothrow_swappable_v<_Tp>) { using std::swap; if (this->_M_is_engaged() && __other._M_is_engaged()) swap(this->_M_get(), __other._M_get()); else if (this->_M_is_engaged()) { __other._M_construct(std::move(this->_M_get())); this->_M_destruct(); } else if (__other._M_is_engaged()) { this->_M_construct(std::move(__other._M_get())); __other._M_destruct(); } } // Observers. constexpr const _Tp* operator->() const { return std::__addressof(this->_M_get()); } constexpr _Tp* operator->() { return std::__addressof(this->_M_get()); } constexpr const _Tp& operator*() const& { return this->_M_get(); } constexpr _Tp& operator*()& { return this->_M_get(); } constexpr _Tp&& operator*()&& { return std::move(this->_M_get()); } constexpr const _Tp&& operator*() const&& { return std::move(this->_M_get()); } constexpr explicit operator bool() const noexcept { return this->_M_is_engaged(); } constexpr bool has_value() const noexcept { return this->_M_is_engaged(); } constexpr const _Tp& value() const& { return this->_M_is_engaged() ? this->_M_get() : (__throw_bad_optional_access(), this->_M_get()); } constexpr _Tp& value()& { return this->_M_is_engaged() ? this->_M_get() : (__throw_bad_optional_access(), this->_M_get()); } constexpr _Tp&& value()&& { return this->_M_is_engaged() ? std::move(this->_M_get()) : (__throw_bad_optional_access(), std::move(this->_M_get())); } constexpr const _Tp&& value() const&& { return this->_M_is_engaged() ? std::move(this->_M_get()) : (__throw_bad_optional_access(), std::move(this->_M_get())); } template constexpr _Tp value_or(_Up&& __u) const& { static_assert(is_copy_constructible_v<_Tp>); static_assert(is_convertible_v<_Up&&, _Tp>); return this->_M_is_engaged() ? this->_M_get() : static_cast<_Tp>(std::forward<_Up>(__u)); } template constexpr _Tp value_or(_Up&& __u) && { static_assert(is_move_constructible_v<_Tp>); static_assert(is_convertible_v<_Up&&, _Tp>); return this->_M_is_engaged() ? std::move(this->_M_get()) : static_cast<_Tp>(std::forward<_Up>(__u)); } void reset() noexcept { this->_M_reset(); } }; template using __optional_relop_t = enable_if_t::value, bool>; // Comparisons between optional values. template constexpr auto operator==(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) -> __optional_relop_t() == declval<_Up>())> { return static_cast(__lhs) == static_cast(__rhs) && (!__lhs || *__lhs == *__rhs); } template constexpr auto operator!=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) -> __optional_relop_t() != declval<_Up>())> { return static_cast(__lhs) != static_cast(__rhs) || (static_cast(__lhs) && *__lhs != *__rhs); } template constexpr auto operator<(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) -> __optional_relop_t() < declval<_Up>())> { return static_cast(__rhs) && (!__lhs || *__lhs < *__rhs); } template constexpr auto operator>(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) -> __optional_relop_t() > declval<_Up>())> { return static_cast(__lhs) && (!__rhs || *__lhs > *__rhs); } template constexpr auto operator<=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) -> __optional_relop_t() <= declval<_Up>())> { return !__lhs || (static_cast(__rhs) && *__lhs <= *__rhs); } template constexpr auto operator>=(const optional<_Tp>& __lhs, const optional<_Up>& __rhs) -> __optional_relop_t() >= declval<_Up>())> { return !__rhs || (static_cast(__lhs) && *__lhs >= *__rhs); } // Comparisons with nullopt. template constexpr bool operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept { return !__lhs; } template constexpr bool operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept { return !__rhs; } template constexpr bool operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept { return static_cast(__lhs); } template constexpr bool operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept { return static_cast(__rhs); } template constexpr bool operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept { return false; } template constexpr bool operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept { return static_cast(__rhs); } template constexpr bool operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept { return static_cast(__lhs); } template constexpr bool operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept { return false; } template constexpr bool operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept { return !__lhs; } template constexpr bool operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept { return true; } template constexpr bool operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept { return true; } template constexpr bool operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept { return !__rhs; } // Comparisons with value type. template constexpr auto operator==(const optional<_Tp>& __lhs, const _Up& __rhs) -> __optional_relop_t() == declval<_Up>())> { return __lhs && *__lhs == __rhs; } template constexpr auto operator==(const _Up& __lhs, const optional<_Tp>& __rhs) -> __optional_relop_t() == declval<_Tp>())> { return __rhs && __lhs == *__rhs; } template constexpr auto operator!=(const optional<_Tp>& __lhs, const _Up& __rhs) -> __optional_relop_t() != declval<_Up>())> { return !__lhs || *__lhs != __rhs; } template constexpr auto operator!=(const _Up& __lhs, const optional<_Tp>& __rhs) -> __optional_relop_t() != declval<_Tp>())> { return !__rhs || __lhs != *__rhs; } template constexpr auto operator<(const optional<_Tp>& __lhs, const _Up& __rhs) -> __optional_relop_t() < declval<_Up>())> { return !__lhs || *__lhs < __rhs; } template constexpr auto operator<(const _Up& __lhs, const optional<_Tp>& __rhs) -> __optional_relop_t() < declval<_Tp>())> { return __rhs && __lhs < *__rhs; } template constexpr auto operator>(const optional<_Tp>& __lhs, const _Up& __rhs) -> __optional_relop_t() > declval<_Up>())> { return __lhs && *__lhs > __rhs; } template constexpr auto operator>(const _Up& __lhs, const optional<_Tp>& __rhs) -> __optional_relop_t() > declval<_Tp>())> { return !__rhs || __lhs > *__rhs; } template constexpr auto operator<=(const optional<_Tp>& __lhs, const _Up& __rhs) -> __optional_relop_t() <= declval<_Up>())> { return !__lhs || *__lhs <= __rhs; } template constexpr auto operator<=(const _Up& __lhs, const optional<_Tp>& __rhs) -> __optional_relop_t() <= declval<_Tp>())> { return __rhs && __lhs <= *__rhs; } template constexpr auto operator>=(const optional<_Tp>& __lhs, const _Up& __rhs) -> __optional_relop_t() >= declval<_Up>())> { return __lhs && *__lhs >= __rhs; } template constexpr auto operator>=(const _Up& __lhs, const optional<_Tp>& __rhs) -> __optional_relop_t() >= declval<_Tp>())> { return !__rhs || __lhs >= *__rhs; } // Swap and creation functions. // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2748. swappable traits for optionals template inline enable_if_t && is_swappable_v<_Tp>> swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs) noexcept(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } template enable_if_t && is_swappable_v<_Tp>)> swap(optional<_Tp>&, optional<_Tp>&) = delete; template constexpr optional> make_optional(_Tp&& __t) { return optional> { std::forward<_Tp>(__t) }; } template constexpr optional<_Tp> make_optional(_Args&&... __args) { return optional<_Tp> { in_place, std::forward<_Args>(__args)... }; } template constexpr optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) { return optional<_Tp> { in_place, __il, std::forward<_Args>(__args)... }; } // Hash. template, bool = __poison_hash<_Up>::__enable_hash_call> struct __optional_hash_call_base { size_t operator()(const optional<_Tp>& __t) const noexcept(noexcept(hash<_Up>{}(*__t))) { // We pick an arbitrary hash for disengaged optionals which hopefully // usual values of _Tp won't typically hash to. constexpr size_t __magic_disengaged_hash = static_cast(-3333); return __t ? hash<_Up>{}(*__t) : __magic_disengaged_hash; } }; template struct __optional_hash_call_base<_Tp, _Up, false> {}; template struct hash> : private __poison_hash>, public __optional_hash_call_base<_Tp> { using result_type [[__deprecated__]] = size_t; using argument_type [[__deprecated__]] = optional<_Tp>; }; template struct __is_fast_hash>> : __is_fast_hash> { }; /// @} #if __cpp_deduction_guides >= 201606 template optional(_Tp) -> optional<_Tp>; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++17 #endif // _GLIBCXX_OPTIONAL 8/chrono000064400000072262152526447520006153 0ustar00// -*- C++ -*- // Copyright (C) 2008-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/chrono * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_CHRONO #define _GLIBCXX_CHRONO 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include // for literals support. #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup chrono Time * @ingroup utilities * * Classes and functions for time. * @{ */ /** @namespace std::chrono * @brief ISO C++ 2011 entities sub-namespace for time and date. */ namespace chrono { template> struct duration; template struct time_point; } // 20.11.4.3 specialization of common_type (for duration, sfinae-friendly) template struct __duration_common_type_wrapper { private: typedef __static_gcd<_Period1::num, _Period2::num> __gcd_num; typedef __static_gcd<_Period1::den, _Period2::den> __gcd_den; typedef typename _CT::type __cr; typedef ratio<__gcd_num::value, (_Period1::den / __gcd_den::value) * _Period2::den> __r; public: typedef __success_type> type; }; template struct __duration_common_type_wrapper<__failure_type, _Period1, _Period2> { typedef __failure_type type; }; template struct common_type, chrono::duration<_Rep2, _Period2>> : public __duration_common_type_wrapper>::type, _Period1, _Period2>::type { }; // 20.11.4.3 specialization of common_type (for time_point, sfinae-friendly) template struct __timepoint_common_type_wrapper { typedef __success_type> type; }; template struct __timepoint_common_type_wrapper<__failure_type, _Clock> { typedef __failure_type type; }; template struct common_type, chrono::time_point<_Clock, _Duration2>> : public __timepoint_common_type_wrapper>::type, _Clock>::type { }; namespace chrono { // Primary template for duration_cast impl. template struct __duration_cast_impl { template static constexpr _ToDur __cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::rep __to_rep; return _ToDur(static_cast<__to_rep>(static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num) / static_cast<_CR>(_CF::den))); } }; template struct __duration_cast_impl<_ToDur, _CF, _CR, true, true> { template static constexpr _ToDur __cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::rep __to_rep; return _ToDur(static_cast<__to_rep>(__d.count())); } }; template struct __duration_cast_impl<_ToDur, _CF, _CR, true, false> { template static constexpr _ToDur __cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::rep __to_rep; return _ToDur(static_cast<__to_rep>( static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den))); } }; template struct __duration_cast_impl<_ToDur, _CF, _CR, false, true> { template static constexpr _ToDur __cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::rep __to_rep; return _ToDur(static_cast<__to_rep>( static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num))); } }; template struct __is_duration : std::false_type { }; template struct __is_duration> : std::true_type { }; template using __enable_if_is_duration = typename enable_if<__is_duration<_Tp>::value, _Tp>::type; template using __disable_if_is_duration = typename enable_if::value, _Tp>::type; /// duration_cast template constexpr __enable_if_is_duration<_ToDur> duration_cast(const duration<_Rep, _Period>& __d) { typedef typename _ToDur::period __to_period; typedef typename _ToDur::rep __to_rep; typedef ratio_divide<_Period, __to_period> __cf; typedef typename common_type<__to_rep, _Rep, intmax_t>::type __cr; typedef __duration_cast_impl<_ToDur, __cf, __cr, __cf::num == 1, __cf::den == 1> __dc; return __dc::__cast(__d); } /// treat_as_floating_point template struct treat_as_floating_point : is_floating_point<_Rep> { }; #if __cplusplus > 201402L template inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; #endif // C++17 #if __cplusplus >= 201703L # define __cpp_lib_chrono 201611 template constexpr __enable_if_is_duration<_ToDur> floor(const duration<_Rep, _Period>& __d) { auto __to = chrono::duration_cast<_ToDur>(__d); if (__to > __d) return __to - _ToDur{1}; return __to; } template constexpr __enable_if_is_duration<_ToDur> ceil(const duration<_Rep, _Period>& __d) { auto __to = chrono::duration_cast<_ToDur>(__d); if (__to < __d) return __to + _ToDur{1}; return __to; } template constexpr enable_if_t< __and_<__is_duration<_ToDur>, __not_>>::value, _ToDur> round(const duration<_Rep, _Period>& __d) { _ToDur __t0 = chrono::floor<_ToDur>(__d); _ToDur __t1 = __t0 + _ToDur{1}; auto __diff0 = __d - __t0; auto __diff1 = __t1 - __d; if (__diff0 == __diff1) { if (__t0.count() & 1) return __t1; return __t0; } else if (__diff0 < __diff1) return __t0; return __t1; } template constexpr enable_if_t::is_signed, duration<_Rep, _Period>> abs(duration<_Rep, _Period> __d) { if (__d >= __d.zero()) return __d; return -__d; } #endif // C++17 /// duration_values template struct duration_values { static constexpr _Rep zero() noexcept { return _Rep(0); } static constexpr _Rep max() noexcept { return numeric_limits<_Rep>::max(); } static constexpr _Rep min() noexcept { return numeric_limits<_Rep>::lowest(); } }; template struct __is_ratio : std::false_type { }; template struct __is_ratio> : std::true_type { }; /// duration template struct duration { private: template using __is_float = treat_as_floating_point<_Rep2>; // _Period2 is an exact multiple of _Period template using __is_harmonic = __bool_constant::den == 1>; public: typedef _Rep rep; typedef _Period period; static_assert(!__is_duration<_Rep>::value, "rep cannot be a duration"); static_assert(__is_ratio<_Period>::value, "period must be a specialization of ratio"); static_assert(_Period::num > 0, "period must be positive"); // 20.11.5.1 construction / copy / destroy constexpr duration() = default; duration(const duration&) = default; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3050. Conversion specification problem in chrono::duration template, __or_<__is_float, __not_<__is_float<_Rep2>>>>> constexpr explicit duration(const _Rep2& __rep) : __r(static_cast(__rep)) { } template, __and_<__is_harmonic<_Period2>, __not_<__is_float<_Rep2>>>>>> constexpr duration(const duration<_Rep2, _Period2>& __d) : __r(duration_cast(__d).count()) { } ~duration() = default; duration& operator=(const duration&) = default; // 20.11.5.2 observer constexpr rep count() const { return __r; } // 20.11.5.3 arithmetic constexpr duration operator+() const { return *this; } constexpr duration operator-() const { return duration(-__r); } _GLIBCXX17_CONSTEXPR duration& operator++() { ++__r; return *this; } _GLIBCXX17_CONSTEXPR duration operator++(int) { return duration(__r++); } _GLIBCXX17_CONSTEXPR duration& operator--() { --__r; return *this; } _GLIBCXX17_CONSTEXPR duration operator--(int) { return duration(__r--); } _GLIBCXX17_CONSTEXPR duration& operator+=(const duration& __d) { __r += __d.count(); return *this; } _GLIBCXX17_CONSTEXPR duration& operator-=(const duration& __d) { __r -= __d.count(); return *this; } _GLIBCXX17_CONSTEXPR duration& operator*=(const rep& __rhs) { __r *= __rhs; return *this; } _GLIBCXX17_CONSTEXPR duration& operator/=(const rep& __rhs) { __r /= __rhs; return *this; } // DR 934. template _GLIBCXX17_CONSTEXPR typename enable_if::value, duration&>::type operator%=(const rep& __rhs) { __r %= __rhs; return *this; } template _GLIBCXX17_CONSTEXPR typename enable_if::value, duration&>::type operator%=(const duration& __d) { __r %= __d.count(); return *this; } // 20.11.5.4 special values static constexpr duration zero() noexcept { return duration(duration_values::zero()); } static constexpr duration min() noexcept { return duration(duration_values::min()); } static constexpr duration max() noexcept { return duration(duration_values::max()); } private: rep __r; }; template constexpr typename common_type, duration<_Rep2, _Period2>>::type operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __cd; return __cd(__cd(__lhs).count() + __cd(__rhs).count()); } template constexpr typename common_type, duration<_Rep2, _Period2>>::type operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __cd; return __cd(__cd(__lhs).count() - __cd(__rhs).count()); } // SFINAE helper to obtain common_type<_Rep1, _Rep2> only if _Rep2 // is implicitly convertible to it. // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3050. Conversion specification problem in chrono::duration constructor template::type> using __common_rep_t = typename enable_if::value, _CRep>::type; template constexpr duration<__common_rep_t<_Rep1, _Rep2>, _Period> operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { typedef duration::type, _Period> __cd; return __cd(__cd(__d).count() * __s); } template constexpr duration<__common_rep_t<_Rep2, _Rep1>, _Period> operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) { return __d * __s; } template constexpr duration<__common_rep_t<_Rep1, __disable_if_is_duration<_Rep2>>, _Period> operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { typedef duration::type, _Period> __cd; return __cd(__cd(__d).count() / __s); } template constexpr typename common_type<_Rep1, _Rep2>::type operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __cd; return __cd(__lhs).count() / __cd(__rhs).count(); } // DR 934. template constexpr duration<__common_rep_t<_Rep1, __disable_if_is_duration<_Rep2>>, _Period> operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { typedef duration::type, _Period> __cd; return __cd(__cd(__d).count() % __s); } template constexpr typename common_type, duration<_Rep2, _Period2>>::type operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __cd; return __cd(__cd(__lhs).count() % __cd(__rhs).count()); } // comparisons template constexpr bool operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __ct; return __ct(__lhs).count() == __ct(__rhs).count(); } template constexpr bool operator<(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<__dur1,__dur2>::type __ct; return __ct(__lhs).count() < __ct(__rhs).count(); } template constexpr bool operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return !(__lhs == __rhs); } template constexpr bool operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return !(__rhs < __lhs); } template constexpr bool operator>(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return __rhs < __lhs; } template constexpr bool operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { return !(__lhs < __rhs); } /// nanoseconds typedef duration nanoseconds; /// microseconds typedef duration microseconds; /// milliseconds typedef duration milliseconds; /// seconds typedef duration seconds; /// minutes typedef duration> minutes; /// hours typedef duration> hours; /// time_point template struct time_point { typedef _Clock clock; typedef _Dur duration; typedef typename duration::rep rep; typedef typename duration::period period; constexpr time_point() : __d(duration::zero()) { } constexpr explicit time_point(const duration& __dur) : __d(__dur) { } // conversions template>> constexpr time_point(const time_point& __t) : __d(__t.time_since_epoch()) { } // observer constexpr duration time_since_epoch() const { return __d; } // arithmetic _GLIBCXX17_CONSTEXPR time_point& operator+=(const duration& __dur) { __d += __dur; return *this; } _GLIBCXX17_CONSTEXPR time_point& operator-=(const duration& __dur) { __d -= __dur; return *this; } // special values static constexpr time_point min() noexcept { return time_point(duration::min()); } static constexpr time_point max() noexcept { return time_point(duration::max()); } private: duration __d; }; /// time_point_cast template constexpr typename enable_if<__is_duration<_ToDur>::value, time_point<_Clock, _ToDur>>::type time_point_cast(const time_point<_Clock, _Dur>& __t) { typedef time_point<_Clock, _ToDur> __time_point; return __time_point(duration_cast<_ToDur>(__t.time_since_epoch())); } #if __cplusplus > 201402L template constexpr enable_if_t<__is_duration<_ToDur>::value, time_point<_Clock, _ToDur>> floor(const time_point<_Clock, _Dur>& __tp) { return time_point<_Clock, _ToDur>{ chrono::floor<_ToDur>(__tp.time_since_epoch())}; } template constexpr enable_if_t<__is_duration<_ToDur>::value, time_point<_Clock, _ToDur>> ceil(const time_point<_Clock, _Dur>& __tp) { return time_point<_Clock, _ToDur>{ chrono::ceil<_ToDur>(__tp.time_since_epoch())}; } template constexpr enable_if_t< __and_<__is_duration<_ToDur>, __not_>>::value, time_point<_Clock, _ToDur>> round(const time_point<_Clock, _Dur>& __tp) { return time_point<_Clock, _ToDur>{ chrono::round<_ToDur>(__tp.time_since_epoch())}; } #endif // C++17 template constexpr time_point<_Clock, typename common_type<_Dur1, duration<_Rep2, _Period2>>::type> operator+(const time_point<_Clock, _Dur1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<_Dur1,__dur2>::type __ct; typedef time_point<_Clock, __ct> __time_point; return __time_point(__lhs.time_since_epoch() + __rhs); } template constexpr time_point<_Clock, typename common_type, _Dur2>::type> operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { typedef duration<_Rep1, _Period1> __dur1; typedef typename common_type<__dur1,_Dur2>::type __ct; typedef time_point<_Clock, __ct> __time_point; return __time_point(__rhs.time_since_epoch() + __lhs); } template constexpr time_point<_Clock, typename common_type<_Dur1, duration<_Rep2, _Period2>>::type> operator-(const time_point<_Clock, _Dur1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<_Dur1,__dur2>::type __ct; typedef time_point<_Clock, __ct> __time_point; return __time_point(__lhs.time_since_epoch() -__rhs); } template constexpr typename common_type<_Dur1, _Dur2>::type operator-(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); } template constexpr bool operator==(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); } template constexpr bool operator!=(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return !(__lhs == __rhs); } template constexpr bool operator<(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return __lhs.time_since_epoch() < __rhs.time_since_epoch(); } template constexpr bool operator<=(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return !(__rhs < __lhs); } template constexpr bool operator>(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return __rhs < __lhs; } template constexpr bool operator>=(const time_point<_Clock, _Dur1>& __lhs, const time_point<_Clock, _Dur2>& __rhs) { return !(__lhs < __rhs); } // Clocks. // Why nanosecond resolution as the default? // Why have std::system_clock always count in the highest // resolution (ie nanoseconds), even if on some OSes the low 3 // or 9 decimal digits will be always zero? This allows later // implementations to change the system_clock::now() // implementation any time to provide better resolution without // changing function signature or units. // To support the (forward) evolution of the library's defined // clocks, wrap inside inline namespace so that the current // defintions of system_clock, steady_clock, and // high_resolution_clock types are uniquely mangled. This way, new // code can use the latests clocks, while the library can contain // compatibility definitions for previous versions. At some // point, when these clocks settle down, the inlined namespaces // can be removed. XXX GLIBCXX_ABI Deprecated inline namespace _V2 { /** * @brief System clock. * * Time returned represents wall time from the system-wide clock. */ struct system_clock { typedef chrono::nanoseconds duration; typedef duration::rep rep; typedef duration::period period; typedef chrono::time_point time_point; static_assert(system_clock::duration::min() < system_clock::duration::zero(), "a clock's minimum duration cannot be less than its epoch"); static constexpr bool is_steady = false; static time_point now() noexcept; // Map to C API static std::time_t to_time_t(const time_point& __t) noexcept { return std::time_t(duration_cast (__t.time_since_epoch()).count()); } static time_point from_time_t(std::time_t __t) noexcept { typedef chrono::time_point __from; return time_point_cast (__from(chrono::seconds(__t))); } }; /** * @brief Monotonic clock * * Time returned has the property of only increasing at a uniform rate. */ struct steady_clock { typedef chrono::nanoseconds duration; typedef duration::rep rep; typedef duration::period period; typedef chrono::time_point time_point; static constexpr bool is_steady = true; static time_point now() noexcept; }; /** * @brief Highest-resolution clock * * This is the clock "with the shortest tick period." Alias to * std::system_clock until higher-than-nanosecond definitions * become feasible. */ using high_resolution_clock = system_clock; } // end inline namespace _V2 } // namespace chrono #if __cplusplus > 201103L #define __cpp_lib_chrono_udls 201304 inline namespace literals { inline namespace chrono_literals { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wliteral-suffix" template struct _Checked_integral_constant : integral_constant<_Rep, static_cast<_Rep>(_Val)> { static_assert(_Checked_integral_constant::value >= 0 && _Checked_integral_constant::value == _Val, "literal value cannot be represented by duration type"); }; template constexpr _Dur __check_overflow() { using _Val = __parse_int::_Parse_int<_Digits...>; using _Rep = typename _Dur::rep; // TODO: should be simply integral_constant<_Rep, _Val::value> // but GCC doesn't reject narrowing conversions to _Rep. using _CheckedVal = _Checked_integral_constant<_Rep, _Val::value>; return _Dur{_CheckedVal::value}; } constexpr chrono::duration> operator""h(long double __hours) { return chrono::duration>{__hours}; } template constexpr chrono::hours operator""h() { return __check_overflow(); } constexpr chrono::duration> operator""min(long double __mins) { return chrono::duration>{__mins}; } template constexpr chrono::minutes operator""min() { return __check_overflow(); } constexpr chrono::duration operator""s(long double __secs) { return chrono::duration{__secs}; } template constexpr chrono::seconds operator""s() { return __check_overflow(); } constexpr chrono::duration operator""ms(long double __msecs) { return chrono::duration{__msecs}; } template constexpr chrono::milliseconds operator""ms() { return __check_overflow(); } constexpr chrono::duration operator""us(long double __usecs) { return chrono::duration{__usecs}; } template constexpr chrono::microseconds operator""us() { return __check_overflow(); } constexpr chrono::duration operator""ns(long double __nsecs) { return chrono::duration{__nsecs}; } template constexpr chrono::nanoseconds operator""ns() { return __check_overflow(); } #pragma GCC diagnostic pop } // inline namespace chrono_literals } // inline namespace literals namespace chrono { using namespace literals::chrono_literals; } // namespace chrono #endif // C++14 // @} group chrono _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif //_GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif //_GLIBCXX_CHRONO 8/cassert000064400000003160152526447520006316 0ustar00// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file cassert * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c assert.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 19.2 Assertions // // No include guards on this header... #pragma GCC system_header #include #include 8/cfloat000064400000003541152526447520006125 0ustar00// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/cfloat * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c float.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 18.2.2 Implementation properties: C library // #pragma GCC system_header #include #include #ifndef _GLIBCXX_CFLOAT #define _GLIBCXX_CFLOAT 1 #if __cplusplus >= 201103L # ifndef DECIMAL_DIG # define DECIMAL_DIG __DECIMAL_DIG__ # endif # ifndef FLT_EVAL_METHOD # define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ # endif #endif #endif 8/exception000064400000011303152526447520006646 0ustar00// Exception Handling support header for -*- C++ -*- // Copyright (C) 1995-2018 Free Software Foundation, Inc. // // This file is part of GCC. // // GCC is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3, or (at your option) // any later version. // // GCC 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 General Public License for more details. // // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file exception * This is a Standard C++ Library header. */ #ifndef __EXCEPTION__ #define __EXCEPTION__ #pragma GCC system_header #pragma GCC visibility push(default) #include #include extern "C++" { namespace std { /** If an %exception is thrown which is not listed in a function's * %exception specification, one of these may be thrown. */ class bad_exception : public exception { public: bad_exception() _GLIBCXX_USE_NOEXCEPT { } // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; // See comment in eh_exception.cc. virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; }; /// If you write a replacement %terminate handler, it must be of this type. typedef void (*terminate_handler) (); /// If you write a replacement %unexpected handler, it must be of this type. typedef void (*unexpected_handler) (); /// Takes a new handler function as an argument, returns the old function. terminate_handler set_terminate(terminate_handler) _GLIBCXX_USE_NOEXCEPT; #if __cplusplus >= 201103L /// Return the current terminate handler. terminate_handler get_terminate() noexcept; #endif /** The runtime will call this function if %exception handling must be * abandoned for any reason. It can also be called by the user. */ void terminate() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__noreturn__)); /// Takes a new handler function as an argument, returns the old function. unexpected_handler set_unexpected(unexpected_handler) _GLIBCXX_USE_NOEXCEPT; #if __cplusplus >= 201103L /// Return the current unexpected handler. unexpected_handler get_unexpected() noexcept; #endif /** The runtime will call this function if an %exception is thrown which * violates the function's %exception specification. */ void unexpected() __attribute__ ((__noreturn__)); /** [18.6.4]/1: 'Returns true after completing evaluation of a * throw-expression until either completing initialization of the * exception-declaration in the matching handler or entering @c unexpected() * due to the throw; or after entering @c terminate() for any reason * other than an explicit call to @c terminate(). [Note: This includes * stack unwinding [15.2]. end note]' * * 2: 'When @c uncaught_exception() is true, throwing an * %exception can result in a call of @c terminate() * (15.5.1).' */ _GLIBCXX17_DEPRECATED bool uncaught_exception() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); #if __cplusplus >= 201703L || !defined(__STRICT_ANSI__) // c++17 or gnu++98 #define __cpp_lib_uncaught_exceptions 201411L /// The number of uncaught exceptions. int uncaught_exceptions() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); #endif // @} group exceptions } // namespace std namespace __gnu_cxx { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief A replacement for the standard terminate_handler which * prints more information about the terminating exception (if any) * on stderr. * * @ingroup exceptions * * Call * @code * std::set_terminate(__gnu_cxx::__verbose_terminate_handler) * @endcode * to use. For more info, see * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt02ch06s02.html * * In 3.4 and later, this is on by default. */ void __verbose_terminate_handler(); _GLIBCXX_END_NAMESPACE_VERSION } // namespace } // extern "C++" #pragma GCC visibility pop #if (__cplusplus >= 201103L) #include #include #endif #endif 8/cctype000064400000004551152526447520006146 0ustar00// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/cctype * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c ctype.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: // #pragma GCC system_header #include #include #ifndef _GLIBCXX_CCTYPE #define _GLIBCXX_CCTYPE 1 // Get rid of those macros defined in in lieu of real functions. #undef isalnum #undef isalpha #undef iscntrl #undef isdigit #undef isgraph #undef islower #undef isprint #undef ispunct #undef isspace #undef isupper #undef isxdigit #undef tolower #undef toupper namespace std { using ::isalnum; using ::isalpha; using ::iscntrl; using ::isdigit; using ::isgraph; using ::islower; using ::isprint; using ::ispunct; using ::isspace; using ::isupper; using ::isxdigit; using ::tolower; using ::toupper; } // namespace std #if __cplusplus >= 201103L #ifdef _GLIBCXX_USE_C99_CTYPE_TR1 #undef isblank namespace std { using ::isblank; } // namespace std #endif // _GLIBCXX_USE_C99_CTYPE_TR1 #endif // C++11 #endif 8/cstddef000064400000014450152526447520006272 0ustar00// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file cstddef * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c stddef.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 18.1 Types // #ifndef _GLIBCXX_CSTDDEF #define _GLIBCXX_CSTDDEF 1 #pragma GCC system_header #undef __need_wchar_t #undef __need_ptrdiff_t #undef __need_size_t #undef __need_NULL #undef __need_wint_t #include #include #if __cplusplus >= 201103L namespace std { // We handle size_t, ptrdiff_t, and nullptr_t in c++config.h. using ::max_align_t; } #endif #if __cplusplus >= 201703L namespace std { #define __cpp_lib_byte 201603 /// std::byte enum class byte : unsigned char {}; template struct __byte_operand { }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; #ifdef _GLIBCXX_USE_WCHAR_T template<> struct __byte_operand { using __type = byte; }; #endif template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; #if defined(__GLIBCXX_TYPE_INT_N_0) template<> struct __byte_operand<__GLIBCXX_TYPE_INT_N_0> { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) template<> struct __byte_operand<__GLIBCXX_TYPE_INT_N_1> { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) template<> struct __byte_operand<__GLIBCXX_TYPE_INT_N_2> { using __type = byte; }; template<> struct __byte_operand { using __type = byte; }; #endif template struct __byte_operand : __byte_operand<_IntegerType> { }; template struct __byte_operand : __byte_operand<_IntegerType> { }; template struct __byte_operand : __byte_operand<_IntegerType> { }; template using __byte_op_t = typename __byte_operand<_IntegerType>::__type; template constexpr __byte_op_t<_IntegerType>& operator<<=(byte& __b, _IntegerType __shift) noexcept { return __b = byte(static_cast(__b) << __shift); } template constexpr __byte_op_t<_IntegerType> operator<<(byte __b, _IntegerType __shift) noexcept { return byte(static_cast(__b) << __shift); } template constexpr __byte_op_t<_IntegerType>& operator>>=(byte& __b, _IntegerType __shift) noexcept { return __b = byte(static_cast(__b) >> __shift); } template constexpr __byte_op_t<_IntegerType> operator>>(byte __b, _IntegerType __shift) noexcept { return byte(static_cast(__b) >> __shift); } constexpr byte& operator|=(byte& __l, byte __r) noexcept { return __l = byte(static_cast(__l) | static_cast(__r)); } constexpr byte operator|(byte __l, byte __r) noexcept { return byte(static_cast(__l) | static_cast(__r)); } constexpr byte& operator&=(byte& __l, byte __r) noexcept { return __l = byte(static_cast(__l) & static_cast(__r)); } constexpr byte operator&(byte __l, byte __r) noexcept { return byte(static_cast(__l) & static_cast(__r)); } constexpr byte& operator^=(byte& __l, byte __r) noexcept { return __l = byte(static_cast(__l) ^ static_cast(__r)); } constexpr byte operator^(byte __l, byte __r) noexcept { return byte(static_cast(__l) ^ static_cast(__r)); } constexpr byte operator~(byte __b) noexcept { return byte(~static_cast(__b)); } template constexpr _IntegerType to_integer(__byte_op_t<_IntegerType> __b) noexcept { return _IntegerType(__b); } } // namespace std #endif #endif // _GLIBCXX_CSTDDEF 8/fstream000064400000107663152526447520006330 0ustar00// File based streams -*- C++ -*- // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/fstream * This is a Standard C++ Library header. */ // // ISO C++ 14882: 27.8 File-based streams // #ifndef _GLIBCXX_FSTREAM #define _GLIBCXX_FSTREAM 1 #pragma GCC system_header #include #include #include #include // For BUFSIZ #include // For __basic_file, __c_lock #if __cplusplus >= 201103L #include // For std::string overloads. #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201703L // Enable if _Path is a filesystem::path or experimental::filesystem::path template().make_preferred().filename())> using _If_fs_path = enable_if_t, _Result>; #endif // C++17 // [27.8.1.1] template class basic_filebuf /** * @brief The actual work of input and output (for files). * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class associates both its input and output sequence with an * external disk file, and maintains a joint file position for both * sequences. Many of its semantics are described in terms of similar * behavior in the Standard C Library's @c FILE streams. * * Requirements on traits_type, specific to this class: * - traits_type::pos_type must be fpos * - traits_type::off_type must be streamoff * - traits_type::state_type must be Assignable and DefaultConstructible, * - traits_type::state_type() must be the initial state for codecvt. */ template class basic_filebuf : public basic_streambuf<_CharT, _Traits> { #if __cplusplus >= 201103L template using __chk_state = __and_, is_copy_constructible<_Tp>, is_default_constructible<_Tp>>; static_assert(__chk_state::value, "state_type must be CopyAssignable, CopyConstructible" " and DefaultConstructible"); static_assert(is_same>::value, "pos_type must be fpos"); #endif public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; typedef basic_streambuf __streambuf_type; typedef basic_filebuf __filebuf_type; typedef __basic_file __file_type; typedef typename traits_type::state_type __state_type; typedef codecvt __codecvt_type; friend class ios_base; // For sync_with_stdio. protected: // Data Members: // MT lock inherited from libio or other low-level io library. __c_lock _M_lock; // External buffer. __file_type _M_file; /// Place to stash in || out || in | out settings for current filebuf. ios_base::openmode _M_mode; // Beginning state type for codecvt. __state_type _M_state_beg; // During output, the state that corresponds to pptr(), // during input, the state that corresponds to egptr() and // _M_ext_next. __state_type _M_state_cur; // Not used for output. During input, the state that corresponds // to eback() and _M_ext_buf. __state_type _M_state_last; /// Pointer to the beginning of internal buffer. char_type* _M_buf; /** * Actual size of internal buffer. This number is equal to the size * of the put area + 1 position, reserved for the overflow char of * a full area. */ size_t _M_buf_size; // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. bool _M_buf_allocated; /** * _M_reading == false && _M_writing == false for @b uncommitted mode; * _M_reading == true for @b read mode; * _M_writing == true for @b write mode; * * NB: _M_reading == true && _M_writing == true is unused. */ bool _M_reading; bool _M_writing; //@{ /** * Necessary bits for putback buffer management. * * @note pbacks of over one character are not currently supported. */ char_type _M_pback; char_type* _M_pback_cur_save; char_type* _M_pback_end_save; bool _M_pback_init; //@} // Cached codecvt facet. const __codecvt_type* _M_codecvt; /** * Buffer for external characters. Used for input when * codecvt::always_noconv() == false. When valid, this corresponds * to eback(). */ char* _M_ext_buf; /** * Size of buffer held by _M_ext_buf. */ streamsize _M_ext_buf_size; /** * Pointers into the buffer held by _M_ext_buf that delimit a * subsequence of bytes that have been read but not yet converted. * When valid, _M_ext_next corresponds to egptr(). */ const char* _M_ext_next; char* _M_ext_end; /** * Initializes pback buffers, and moves normal buffers to safety. * Assumptions: * _M_in_cur has already been moved back */ void _M_create_pback() { if (!_M_pback_init) { _M_pback_cur_save = this->gptr(); _M_pback_end_save = this->egptr(); this->setg(&_M_pback, &_M_pback, &_M_pback + 1); _M_pback_init = true; } } /** * Deactivates pback buffer contents, and restores normal buffer. * Assumptions: * The pback buffer has only moved forward. */ void _M_destroy_pback() throw() { if (_M_pback_init) { // Length _M_in_cur moved in the pback buffer. _M_pback_cur_save += this->gptr() != this->eback(); this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save); _M_pback_init = false; } } public: // Constructors/destructor: /** * @brief Does not open any files. * * The default constructor initializes the parent class using its * own default ctor. */ basic_filebuf(); #if __cplusplus >= 201103L basic_filebuf(const basic_filebuf&) = delete; basic_filebuf(basic_filebuf&&); #endif /** * @brief The destructor closes the file first. */ virtual ~basic_filebuf() { this->close(); } #if __cplusplus >= 201103L basic_filebuf& operator=(const basic_filebuf&) = delete; basic_filebuf& operator=(basic_filebuf&&); void swap(basic_filebuf&); #endif // Members: /** * @brief Returns true if the external file is open. */ bool is_open() const throw() { return _M_file.is_open(); } /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * @return @c this on success, NULL on failure * * If a file is already open, this function immediately fails. * Otherwise it tries to open the file named @a __s using the flags * given in @a __mode. * * Table 92, adapted here, gives the relation between openmode * combinations and the equivalent @c fopen() flags. * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app, * and binary|in|app per DR 596) *
       *  +---------------------------------------------------------+
       *  | ios_base Flag combination            stdio equivalent   |
       *  |binary  in  out  trunc  app                              |
       *  +---------------------------------------------------------+
       *  |             +                        w                  |
       *  |             +           +            a                  |
       *  |                         +            a                  |
       *  |             +     +                  w                  |
       *  |         +                            r                  |
       *  |         +   +                        r+                 |
       *  |         +   +     +                  w+                 |
       *  |         +   +           +            a+                 |
       *  |         +               +            a+                 |
       *  +---------------------------------------------------------+
       *  |   +         +                        wb                 |
       *  |   +         +           +            ab                 |
       *  |   +                     +            ab                 |
       *  |   +         +     +                  wb                 |
       *  |   +     +                            rb                 |
       *  |   +     +   +                        r+b                |
       *  |   +     +   +     +                  w+b                |
       *  |   +     +   +           +            a+b                |
       *  |   +     +               +            a+b                |
       *  +---------------------------------------------------------+
       *  
*/ __filebuf_type* open(const char* __s, ios_base::openmode __mode); #if __cplusplus >= 201103L /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * @return @c this on success, NULL on failure */ __filebuf_type* open(const std::string& __s, ios_base::openmode __mode) { return open(__s.c_str(), __mode); } #if __cplusplus >= 201703L /** * @brief Opens an external file. * @param __s The name of the file, as a filesystem::path. * @param __mode The open mode flags. * @return @c this on success, NULL on failure */ template _If_fs_path<_Path, __filebuf_type*> open(const _Path& __s, ios_base::openmode __mode) { return open(__s.c_str(), __mode); } #endif // C++17 #endif // C++11 /** * @brief Closes the currently associated file. * @return @c this on success, NULL on failure * * If no file is currently open, this function immediately fails. * * If a put buffer area exists, @c overflow(eof) is * called to flush all the characters. The file is then * closed. * * If any operations fail, this function also fails. */ __filebuf_type* close(); protected: void _M_allocate_internal_buffer(); void _M_destroy_internal_buffer() throw(); // [27.8.1.4] overridden virtual functions virtual streamsize showmanyc(); // Stroustrup, 1998, p. 628 // underflow() and uflow() functions are called to get the next // character from the real input source when the buffer is empty. // Buffered input uses underflow() virtual int_type underflow(); virtual int_type pbackfail(int_type __c = _Traits::eof()); // Stroustrup, 1998, p 648 // The overflow() function is called to transfer characters to the // real output destination when the buffer is full. A call to // overflow(c) outputs the contents of the buffer plus the // character c. // 27.5.2.4.5 // Consume some sequence of the characters in the pending sequence. virtual int_type overflow(int_type __c = _Traits::eof()); // Convert internal byte sequence to external, char-based // sequence via codecvt. bool _M_convert_to_external(char_type*, streamsize); /** * @brief Manipulates the buffer. * @param __s Pointer to a buffer area. * @param __n Size of @a __s. * @return @c this * * If no file has been opened, and both @a __s and @a __n are zero, then * the stream becomes unbuffered. Otherwise, @c __s is used as a * buffer; see * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering * for more. */ virtual __streambuf_type* setbuf(char_type* __s, streamsize __n); virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode = ios_base::in | ios_base::out); virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode = ios_base::in | ios_base::out); // Common code for seekoff, seekpos, and overflow pos_type _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); int _M_get_ext_pos(__state_type &__state); virtual int sync(); virtual void imbue(const locale& __loc); virtual streamsize xsgetn(char_type* __s, streamsize __n); virtual streamsize xsputn(const char_type* __s, streamsize __n); // Flushes output buffer, then writes unshift sequence. bool _M_terminate_output(); /** * This function sets the pointers of the internal buffer, both get * and put areas. Typically: * * __off == egptr() - eback() upon underflow/uflow (@b read mode); * __off == 0 upon overflow (@b write mode); * __off == -1 upon open, setbuf, seekoff/pos (@b uncommitted mode). * * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size * reflects the actual allocated memory and the last cell is reserved * for the overflow char of a full put area. */ void _M_set_buffer(streamsize __off) { const bool __testin = _M_mode & ios_base::in; const bool __testout = (_M_mode & ios_base::out || _M_mode & ios_base::app); if (__testin && __off > 0) this->setg(_M_buf, _M_buf, _M_buf + __off); else this->setg(_M_buf, _M_buf, _M_buf); if (__testout && __off == 0 && _M_buf_size > 1 ) this->setp(_M_buf, _M_buf + _M_buf_size - 1); else this->setp(0, 0); } }; // [27.8.1.5] Template class basic_ifstream /** * @brief Controlling input for files. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class supports reading from named files, using the inherited * functions from std::basic_istream. To control the associated * sequence, an instance of std::basic_filebuf is used, which this page * refers to as @c sb. */ template class basic_ifstream : public basic_istream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef basic_filebuf __filebuf_type; typedef basic_istream __istream_type; private: __filebuf_type _M_filebuf; public: // Constructors/Destructors: /** * @brief Default constructor. * * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ basic_ifstream() : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** * @brief Create an input file stream. * @param __s Null terminated string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::in is automatically included in @a __mode. */ explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201103L /** * @brief Create an input file stream. * @param __s std::string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::in is automatically included in @a __mode. */ explicit basic_ifstream(const std::string& __s, ios_base::openmode __mode = ios_base::in) : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201703L /** * @param Create an input file stream. * @param __s filesystem::path specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::in is automatically included in @a __mode. */ template> basic_ifstream(const _Path& __s, ios_base::openmode __mode = ios_base::in) : basic_ifstream(__s.c_str(), __mode) { } #endif // C++17 basic_ifstream(const basic_ifstream&) = delete; basic_ifstream(basic_ifstream&& __rhs) : __istream_type(std::move(__rhs)), _M_filebuf(std::move(__rhs._M_filebuf)) { __istream_type::set_rdbuf(&_M_filebuf); } #endif // C++11 /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. */ ~basic_ifstream() { } #if __cplusplus >= 201103L // 27.8.3.2 Assign and swap: basic_ifstream& operator=(const basic_ifstream&) = delete; basic_ifstream& operator=(basic_ifstream&& __rhs) { __istream_type::operator=(std::move(__rhs)); _M_filebuf = std::move(__rhs._M_filebuf); return *this; } void swap(basic_ifstream& __rhs) { __istream_type::swap(__rhs); _M_filebuf.swap(__rhs._M_filebuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() */ bool is_open() { return _M_filebuf.is_open(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 365. Lack of const-qualification in clause 27 bool is_open() const { return _M_filebuf.is_open(); } /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(s,__mode|in). If that function * fails, @c failbit is set in the stream's error state. */ void open(const char* __s, ios_base::openmode __mode = ios_base::in) { if (!_M_filebuf.open(__s, __mode | ios_base::in)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201103L /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function * fails, @c failbit is set in the stream's error state. */ void open(const std::string& __s, ios_base::openmode __mode = ios_base::in) { if (!_M_filebuf.open(__s, __mode | ios_base::in)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201703L /** * @brief Opens an external file. * @param __s The name of the file, as a filesystem::path. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function * fails, @c failbit is set in the stream's error state. */ template _If_fs_path<_Path, void> open(const _Path& __s, ios_base::openmode __mode = ios_base::in) { open(__s.c_str(), __mode); } #endif // C++17 #endif // C++11 /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. */ void close() { if (!_M_filebuf.close()) this->setstate(ios_base::failbit); } }; // [27.8.1.8] Template class basic_ofstream /** * @brief Controlling output for files. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class supports reading from named files, using the inherited * functions from std::basic_ostream. To control the associated * sequence, an instance of std::basic_filebuf is used, which this page * refers to as @c sb. */ template class basic_ofstream : public basic_ostream<_CharT,_Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef basic_filebuf __filebuf_type; typedef basic_ostream __ostream_type; private: __filebuf_type _M_filebuf; public: // Constructors: /** * @brief Default constructor. * * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ basic_ofstream(): __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** * @brief Create an output file stream. * @param __s Null terminated string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::out is automatically included in @a __mode. */ explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out) : __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201103L /** * @brief Create an output file stream. * @param __s std::string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::out is automatically included in @a __mode. */ explicit basic_ofstream(const std::string& __s, ios_base::openmode __mode = ios_base::out) : __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201703L /** * @param Create an output file stream. * @param __s filesystem::path specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::out is automatically included in @a __mode. */ template> basic_ofstream(const _Path& __s, ios_base::openmode __mode = ios_base::out) : basic_ofstream(__s.c_str(), __mode) { } #endif // C++17 basic_ofstream(const basic_ofstream&) = delete; basic_ofstream(basic_ofstream&& __rhs) : __ostream_type(std::move(__rhs)), _M_filebuf(std::move(__rhs._M_filebuf)) { __ostream_type::set_rdbuf(&_M_filebuf); } #endif /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. */ ~basic_ofstream() { } #if __cplusplus >= 201103L // 27.8.3.2 Assign and swap: basic_ofstream& operator=(const basic_ofstream&) = delete; basic_ofstream& operator=(basic_ofstream&& __rhs) { __ostream_type::operator=(std::move(__rhs)); _M_filebuf = std::move(__rhs._M_filebuf); return *this; } void swap(basic_ofstream& __rhs) { __ostream_type::swap(__rhs); _M_filebuf.swap(__rhs._M_filebuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() */ bool is_open() { return _M_filebuf.is_open(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 365. Lack of const-qualification in clause 27 bool is_open() const { return _M_filebuf.is_open(); } /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode|out). If that * function fails, @c failbit is set in the stream's error state. */ void open(const char* __s, ios_base::openmode __mode = ios_base::out) { if (!_M_filebuf.open(__s, __mode | ios_base::out)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201103L /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(s,mode|out). If that * function fails, @c failbit is set in the stream's error state. */ void open(const std::string& __s, ios_base::openmode __mode = ios_base::out) { if (!_M_filebuf.open(__s, __mode | ios_base::out)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201703L /** * @brief Opens an external file. * @param __s The name of the file, as a filesystem::path. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode|out). If that * function fails, @c failbit is set in the stream's error state. */ template _If_fs_path<_Path, void> open(const _Path& __s, ios_base::openmode __mode = ios_base::out) { open(__s.c_str(), __mode); } #endif // C++17 #endif // C++11 /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. */ void close() { if (!_M_filebuf.close()) this->setstate(ios_base::failbit); } }; // [27.8.1.11] Template class basic_fstream /** * @brief Controlling input and output for files. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class supports reading from and writing to named files, using * the inherited functions from std::basic_iostream. To control the * associated sequence, an instance of std::basic_filebuf is used, which * this page refers to as @c sb. */ template class basic_fstream : public basic_iostream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef basic_filebuf __filebuf_type; typedef basic_ios __ios_type; typedef basic_iostream __iostream_type; private: __filebuf_type _M_filebuf; public: // Constructors/destructor: /** * @brief Default constructor. * * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ basic_fstream() : __iostream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** * @brief Create an input/output file stream. * @param __s Null terminated string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). */ explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out) : __iostream_type(0), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201103L /** * @brief Create an input/output file stream. * @param __s Null terminated string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). */ explicit basic_fstream(const std::string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out) : __iostream_type(0), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201703L /** * @param Create an input/output file stream. * @param __s filesystem::path specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). */ template> basic_fstream(const _Path& __s, ios_base::openmode __mode = ios_base::in | ios_base::out) : basic_fstream(__s.c_str(), __mode) { } #endif // C++17 basic_fstream(const basic_fstream&) = delete; basic_fstream(basic_fstream&& __rhs) : __iostream_type(std::move(__rhs)), _M_filebuf(std::move(__rhs._M_filebuf)) { __iostream_type::set_rdbuf(&_M_filebuf); } #endif /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. */ ~basic_fstream() { } #if __cplusplus >= 201103L // 27.8.3.2 Assign and swap: basic_fstream& operator=(const basic_fstream&) = delete; basic_fstream& operator=(basic_fstream&& __rhs) { __iostream_type::operator=(std::move(__rhs)); _M_filebuf = std::move(__rhs._M_filebuf); return *this; } void swap(basic_fstream& __rhs) { __iostream_type::swap(__rhs); _M_filebuf.swap(__rhs._M_filebuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() */ bool is_open() { return _M_filebuf.is_open(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 365. Lack of const-qualification in clause 27 bool is_open() const { return _M_filebuf.is_open(); } /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode). If that * function fails, @c failbit is set in the stream's error state. */ void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out) { if (!_M_filebuf.open(__s, __mode)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201103L /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode). If that * function fails, @c failbit is set in the stream's error state. */ void open(const std::string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out) { if (!_M_filebuf.open(__s, __mode)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201703L /** * @brief Opens an external file. * @param __s The name of the file, as a filesystem::path. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode). If that * function fails, @c failbit is set in the stream's error state. */ template _If_fs_path<_Path, void> open(const _Path& __s, ios_base::openmode __mode = ios_base::in | ios_base::out) { open(__s.c_str(), __mode); } #endif // C++17 #endif // C++11 /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. */ void close() { if (!_M_filebuf.close()) this->setstate(ios_base::failbit); } }; #if __cplusplus >= 201103L /// Swap specialization for filebufs. template inline void swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) { __x.swap(__y); } /// Swap specialization for ifstreams. template inline void swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) { __x.swap(__y); } /// Swap specialization for ofstreams. template inline void swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) { __x.swap(__y); } /// Swap specialization for fstreams. template inline void swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) { __x.swap(__y); } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include #endif /* _GLIBCXX_FSTREAM */ 8/parallel/set_operations.h000064400000034376152526447520011747 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** * @file parallel/set_operations.h * @brief Parallel implementations of set operations for random-access * iterators. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Marius Elvert and Felix Bondarenko. #ifndef _GLIBCXX_PARALLEL_SET_OPERATIONS_H #define _GLIBCXX_PARALLEL_SET_OPERATIONS_H 1 #include #include #include namespace __gnu_parallel { template _OutputIterator __copy_tail(std::pair<_IIter, _IIter> __b, std::pair<_IIter, _IIter> __e, _OutputIterator __r) { if (__b.first != __e.first) { do { *__r++ = *__b.first++; } while (__b.first != __e.first); } else { while (__b.second != __e.second) *__r++ = *__b.second++; } return __r; } template struct __symmetric_difference_func { typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename std::pair<_IIter, _IIter> _IteratorPair; __symmetric_difference_func(_Compare __comp) : _M_comp(__comp) {} _Compare _M_comp; _OutputIterator _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d, _OutputIterator __r) const { while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { *__r = *__a; ++__a; ++__r; } else if (_M_comp(*__c, *__a)) { *__r = *__c; ++__c; ++__r; } else { ++__a; ++__c; } } return std::copy(__c, __d, std::copy(__a, __b, __r)); } _DifferenceType __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const { _DifferenceType __counter = 0; while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; ++__counter; } else if (_M_comp(*__c, *__a)) { ++__c; ++__counter; } else { ++__a; ++__c; } } return __counter + (__b - __a) + (__d - __c); } _OutputIterator __first_empty(_IIter __c, _IIter __d, _OutputIterator __out) const { return std::copy(__c, __d, __out); } _OutputIterator __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const { return std::copy(__a, __b, __out); } }; template struct __difference_func { typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename std::pair<_IIter, _IIter> _IteratorPair; __difference_func(_Compare __comp) : _M_comp(__comp) {} _Compare _M_comp; _OutputIterator _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d, _OutputIterator __r) const { while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { *__r = *__a; ++__a; ++__r; } else if (_M_comp(*__c, *__a)) { ++__c; } else { ++__a; ++__c; } } return std::copy(__a, __b, __r); } _DifferenceType __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const { _DifferenceType __counter = 0; while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; ++__counter; } else if (_M_comp(*__c, *__a)) { ++__c; } else { ++__a; ++__c; } } return __counter + (__b - __a); } _OutputIterator __first_empty(_IIter, _IIter, _OutputIterator __out) const { return __out; } _OutputIterator __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const { return std::copy(__a, __b, __out); } }; template struct __intersection_func { typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename std::pair<_IIter, _IIter> _IteratorPair; __intersection_func(_Compare __comp) : _M_comp(__comp) {} _Compare _M_comp; _OutputIterator _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d, _OutputIterator __r) const { while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; } else if (_M_comp(*__c, *__a)) { ++__c; } else { *__r = *__a; ++__a; ++__c; ++__r; } } return __r; } _DifferenceType __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const { _DifferenceType __counter = 0; while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; } else if (_M_comp(*__c, *__a)) { ++__c; } else { ++__a; ++__c; ++__counter; } } return __counter; } _OutputIterator __first_empty(_IIter, _IIter, _OutputIterator __out) const { return __out; } _OutputIterator __second_empty(_IIter, _IIter, _OutputIterator __out) const { return __out; } }; template struct __union_func { typedef typename std::iterator_traits<_IIter>::difference_type _DifferenceType; __union_func(_Compare __comp) : _M_comp(__comp) {} _Compare _M_comp; _OutputIterator _M_invoke(_IIter __a, const _IIter __b, _IIter __c, const _IIter __d, _OutputIterator __r) const { while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { *__r = *__a; ++__a; } else if (_M_comp(*__c, *__a)) { *__r = *__c; ++__c; } else { *__r = *__a; ++__a; ++__c; } ++__r; } return std::copy(__c, __d, std::copy(__a, __b, __r)); } _DifferenceType __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const { _DifferenceType __counter = 0; while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; } else if (_M_comp(*__c, *__a)) { ++__c; } else { ++__a; ++__c; } ++__counter; } __counter += (__b - __a); __counter += (__d - __c); return __counter; } _OutputIterator __first_empty(_IIter __c, _IIter __d, _OutputIterator __out) const { return std::copy(__c, __d, __out); } _OutputIterator __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const { return std::copy(__a, __b, __out); } }; template _OutputIterator __parallel_set_operation(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Operation __op) { _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2)) typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename std::pair<_IIter, _IIter> _IteratorPair; if (__begin1 == __end1) return __op.__first_empty(__begin2, __end2, __result); if (__begin2 == __end2) return __op.__second_empty(__begin1, __end1, __result); const _DifferenceType __size = (__end1 - __begin1) + (__end2 - __begin2); const _IteratorPair __sequence[2] = { std::make_pair(__begin1, __end1), std::make_pair(__begin2, __end2) }; _OutputIterator __return_value = __result; _DifferenceType *__borders; _IteratorPair *__block_begins; _DifferenceType* __lengths; _ThreadIndex __num_threads = std::min<_DifferenceType>(__get_max_threads(), std::min(__end1 - __begin1, __end2 - __begin2)); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __borders = new _DifferenceType[__num_threads + 2]; __equally_split(__size, __num_threads + 1, __borders); __block_begins = new _IteratorPair[__num_threads + 1]; // Very __start. __block_begins[0] = std::make_pair(__begin1, __begin2); __lengths = new _DifferenceType[__num_threads]; } //single _ThreadIndex __iam = omp_get_thread_num(); // _Result from multiseq_partition. _IIter __offset[2]; const _DifferenceType __rank = __borders[__iam + 1]; multiseq_partition(__sequence, __sequence + 2, __rank, __offset, __op._M_comp); // allowed to read? // together // *(__offset[ 0 ] - 1) == *__offset[ 1 ] if (__offset[ 0 ] != __begin1 && __offset[1] != __end2 && !__op._M_comp(*(__offset[0] - 1), *__offset[1]) && !__op._M_comp(*__offset[1], *(__offset[0] - 1))) { // Avoid split between globally equal elements: move one to // front in first sequence. --__offset[0]; } _IteratorPair __block_end = __block_begins[__iam + 1] = _IteratorPair(__offset[0], __offset[1]); // Make sure all threads have their block_begin result written out. # pragma omp barrier _IteratorPair __block_begin = __block_begins[__iam]; // Begin working for the first block, while the others except // the last start to count. if (__iam == 0) { // The first thread can copy already. __lengths[ __iam ] = __op._M_invoke(__block_begin.first, __block_end.first, __block_begin.second, __block_end.second, __result) - __result; } else { __lengths[ __iam ] = __op.__count(__block_begin.first, __block_end.first, __block_begin.second, __block_end.second); } // Make sure everyone wrote their lengths. # pragma omp barrier _OutputIterator __r = __result; if (__iam == 0) { // Do the last block. for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __r += __lengths[__i]; __block_begin = __block_begins[__num_threads]; // Return the result iterator of the last block. __return_value = __op._M_invoke(__block_begin.first, __end1, __block_begin.second, __end2, __r); } else { for (_ThreadIndex __i = 0; __i < __iam; ++__i) __r += __lengths[ __i ]; // Reset begins for copy pass. __op._M_invoke(__block_begin.first, __block_end.first, __block_begin.second, __block_end.second, __r); } } return __return_value; } template inline _OutputIterator __parallel_set_union(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) { return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result, __union_func< _IIter, _OutputIterator, _Compare>(__comp)); } template inline _OutputIterator __parallel_set_intersection(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) { return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result, __intersection_func<_IIter, _OutputIterator, _Compare>(__comp)); } template inline _OutputIterator __parallel_set_difference(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) { return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result, __difference_func<_IIter, _OutputIterator, _Compare>(__comp)); } template inline _OutputIterator __parallel_set_symmetric_difference(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) { return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result, __symmetric_difference_func<_IIter, _OutputIterator, _Compare>(__comp)); } } #endif /* _GLIBCXX_PARALLEL_SET_OPERATIONS_H */ 8/parallel/features.h000064400000006727152526447520010526 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/features.h * @brief Defines on whether to include algorithm variants. * * Less variants reduce executable size and compile time. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_FEATURES_H #define _GLIBCXX_PARALLEL_FEATURES_H 1 #ifndef _GLIBCXX_MERGESORT /** @def _GLIBCXX_MERGESORT * @brief Include parallel multi-way mergesort. * @see __gnu_parallel::_Settings::sort_algorithm */ #define _GLIBCXX_MERGESORT 1 #endif #ifndef _GLIBCXX_QUICKSORT /** @def _GLIBCXX_QUICKSORT * @brief Include parallel unbalanced quicksort. * @see __gnu_parallel::_Settings::sort_algorithm */ #define _GLIBCXX_QUICKSORT 1 #endif #ifndef _GLIBCXX_BAL_QUICKSORT /** @def _GLIBCXX_BAL_QUICKSORT * @brief Include parallel dynamically load-balanced quicksort. * @see __gnu_parallel::_Settings::sort_algorithm */ #define _GLIBCXX_BAL_QUICKSORT 1 #endif #ifndef _GLIBCXX_FIND_GROWING_BLOCKS /** @brief Include the growing blocks variant for std::find. * @see __gnu_parallel::_Settings::find_algorithm */ #define _GLIBCXX_FIND_GROWING_BLOCKS 1 #endif #ifndef _GLIBCXX_FIND_CONSTANT_SIZE_BLOCKS /** @brief Include the equal-sized blocks variant for std::find. * @see __gnu_parallel::_Settings::find_algorithm */ #define _GLIBCXX_FIND_CONSTANT_SIZE_BLOCKS 1 #endif #ifndef _GLIBCXX_FIND_EQUAL_SPLIT /** @def _GLIBCXX_FIND_EQUAL_SPLIT * @brief Include the equal splitting variant for std::find. * @see __gnu_parallel::_Settings::find_algorithm */ #define _GLIBCXX_FIND_EQUAL_SPLIT 1 #endif #ifndef _GLIBCXX_TREE_INITIAL_SPLITTING /** @def _GLIBCXX_TREE_INITIAL_SPLITTING * @brief Include the initial splitting variant for * _Rb_tree::insert_unique(_IIter beg, _IIter __end). * @see __gnu_parallel::_Rb_tree */ #define _GLIBCXX_TREE_INITIAL_SPLITTING 1 #endif #ifndef _GLIBCXX_TREE_DYNAMIC_BALANCING /** @def _GLIBCXX_TREE_DYNAMIC_BALANCING * @brief Include the dynamic balancing variant for * _Rb_tree::insert_unique(_IIter beg, _IIter __end). * @see __gnu_parallel::_Rb_tree */ #define _GLIBCXX_TREE_DYNAMIC_BALANCING 1 #endif #ifndef _GLIBCXX_TREE_FULL_COPY /** @def _GLIBCXX_TREE_FULL_COPY * @brief In order to sort the input sequence of * _Rb_tree::insert_unique(_IIter beg, _IIter __end) a * full copy of the input elements is done. * @see __gnu_parallel::_Rb_tree */ #define _GLIBCXX_TREE_FULL_COPY 1 #endif #endif /* _GLIBCXX_PARALLEL_FEATURES_H */ 8/parallel/compatibility.h000064400000007316152526447520011554 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/compatibility.h * @brief Compatibility layer, mostly concerned with atomic operations. * * This file is a GNU parallel extension to the Standard C++ Library * and contains implementation details for the library's internal use. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_COMPATIBILITY_H #define _GLIBCXX_PARALLEL_COMPATIBILITY_H 1 #include #include #if !defined(_WIN32) || defined (__CYGWIN__) #include #endif #ifdef __MINGW32__ // Including will drag in all the windows32 names. Since // that can cause user code portability problems, we just declare the // one needed function here. extern "C" __attribute((dllimport)) void __attribute__((stdcall)) Sleep (unsigned long); #endif namespace __gnu_parallel { template inline _Tp __add_omp(volatile _Tp* __ptr, _Tp __addend) { int64_t __res; #pragma omp critical { __res = *__ptr; *(__ptr) += __addend; } return __res; } /** @brief Add a value to a variable, atomically. * * @param __ptr Pointer to a signed integer. * @param __addend Value to add. */ template inline _Tp __fetch_and_add(volatile _Tp* __ptr, _Tp __addend) { if (__atomic_always_lock_free(sizeof(_Tp), __ptr)) return __atomic_fetch_add(__ptr, __addend, __ATOMIC_ACQ_REL); return __add_omp(__ptr, __addend); } template inline bool __cas_omp(volatile _Tp* __ptr, _Tp __comparand, _Tp __replacement) { bool __res = false; #pragma omp critical { if (*__ptr == __comparand) { *__ptr = __replacement; __res = true; } } return __res; } /** @brief Compare-and-swap * * Compare @c *__ptr and @c __comparand. If equal, let @c * *__ptr=__replacement and return @c true, return @c false otherwise. * * @param __ptr Pointer to signed integer. * @param __comparand Compare value. * @param __replacement Replacement value. */ template inline bool __compare_and_swap(volatile _Tp* __ptr, _Tp __comparand, _Tp __replacement) { if (__atomic_always_lock_free(sizeof(_Tp), __ptr)) return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, false, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); return __cas_omp(__ptr, __comparand, __replacement); } /** @brief Yield control to another thread, without waiting for * the end of the time slice. */ inline void __yield() { #if defined (_WIN32) && !defined (__CYGWIN__) Sleep(0); #else sched_yield(); #endif } } // end namespace #endif /* _GLIBCXX_PARALLEL_COMPATIBILITY_H */ 8/parallel/iterator.h000064400000013056152526447520010532 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/iterator.h * @brief Helper iterator classes for the std::transform() functions. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_ITERATOR_H #define _GLIBCXX_PARALLEL_ITERATOR_H 1 #include #include namespace __gnu_parallel { /** @brief A pair of iterators. The usual iterator operations are * applied to both child iterators. */ template class _IteratorPair : public std::pair<_Iterator1, _Iterator2> { private: typedef std::pair<_Iterator1, _Iterator2> _Base; public: typedef _IteratorCategory iterator_category; typedef void value_type; typedef std::iterator_traits<_Iterator1> _TraitsType; typedef typename _TraitsType::difference_type difference_type; typedef _IteratorPair* pointer; typedef _IteratorPair& reference; _IteratorPair() { } _IteratorPair(const _Iterator1& __first, const _Iterator2& __second) : _Base(__first, __second) { } // Pre-increment operator. _IteratorPair& operator++() { ++_Base::first; ++_Base::second; return *this; } // Post-increment operator. const _IteratorPair operator++(int) { return _IteratorPair(_Base::first++, _Base::second++); } // Pre-decrement operator. _IteratorPair& operator--() { --_Base::first; --_Base::second; return *this; } // Post-decrement operator. const _IteratorPair operator--(int) { return _IteratorPair(_Base::first--, _Base::second--); } // Type conversion. operator _Iterator2() const { return _Base::second; } _IteratorPair& operator=(const _IteratorPair& __other) { _Base::first = __other.first; _Base::second = __other.second; return *this; } _IteratorPair operator+(difference_type __delta) const { return _IteratorPair(_Base::first + __delta, _Base::second + __delta); } difference_type operator-(const _IteratorPair& __other) const { return _Base::first - __other.first; } }; /** @brief A triple of iterators. The usual iterator operations are applied to all three child iterators. */ template class _IteratorTriple { public: typedef _IteratorCategory iterator_category; typedef void value_type; typedef typename std::iterator_traits<_Iterator1>::difference_type difference_type; typedef _IteratorTriple* pointer; typedef _IteratorTriple& reference; _Iterator1 _M_first; _Iterator2 _M_second; _Iterator3 _M_third; _IteratorTriple() { } _IteratorTriple(const _Iterator1& __first, const _Iterator2& __second, const _Iterator3& __third) { _M_first = __first; _M_second = __second; _M_third = __third; } // Pre-increment operator. _IteratorTriple& operator++() { ++_M_first; ++_M_second; ++_M_third; return *this; } // Post-increment operator. const _IteratorTriple operator++(int) { return _IteratorTriple(_M_first++, _M_second++, _M_third++); } // Pre-decrement operator. _IteratorTriple& operator--() { --_M_first; --_M_second; --_M_third; return *this; } // Post-decrement operator. const _IteratorTriple operator--(int) { return _IteratorTriple(_M_first--, _M_second--, _M_third--); } // Type conversion. operator _Iterator3() const { return _M_third; } _IteratorTriple& operator=(const _IteratorTriple& __other) { _M_first = __other._M_first; _M_second = __other._M_second; _M_third = __other._M_third; return *this; } _IteratorTriple operator+(difference_type __delta) const { return _IteratorTriple(_M_first + __delta, _M_second + __delta, _M_third + __delta); } difference_type operator-(const _IteratorTriple& __other) const { return _M_first - __other._M_first; } }; } #endif /* _GLIBCXX_PARALLEL_ITERATOR_H */ 8/parallel/unique_copy.h000064400000014025152526447520011236 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/unique_copy.h * @brief Parallel implementations of std::unique_copy(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Robert Geisberger and Robin Dapp. #ifndef _GLIBCXX_PARALLEL_UNIQUE_COPY_H #define _GLIBCXX_PARALLEL_UNIQUE_COPY_H 1 #include #include namespace __gnu_parallel { /** @brief Parallel std::unique_copy(), w/__o explicit equality predicate. * @param __first Begin iterator of input sequence. * @param __last End iterator of input sequence. * @param __result Begin iterator of result __sequence. * @param __binary_pred Equality predicate. * @return End iterator of result __sequence. */ template _OutputIterator __parallel_unique_copy(_IIter __first, _IIter __last, _OutputIterator __result, _BinaryPredicate __binary_pred) { _GLIBCXX_CALL(__last - __first) typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __size = __last - __first; if (__size == 0) return __result; // Let the first thread process two parts. _DifferenceType *__counter; _DifferenceType *__borders; _ThreadIndex __num_threads = __get_max_threads(); // First part contains at least one element. # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __borders = new _DifferenceType[__num_threads + 2]; __equally_split(__size, __num_threads + 1, __borders); __counter = new _DifferenceType[__num_threads + 1]; } _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __begin, __end; // Check for length without duplicates // Needed for position in output _DifferenceType __i = 0; _OutputIterator __out = __result; if (__iam == 0) { __begin = __borders[0] + 1; // == 1 __end = __borders[__iam + 1]; ++__i; *__out++ = *__first; for (_IIter __iter = __first + __begin; __iter < __first + __end; ++__iter) { if (!__binary_pred(*__iter, *(__iter - 1))) { ++__i; *__out++ = *__iter; } } } else { __begin = __borders[__iam]; //one part __end = __borders[__iam + 1]; for (_IIter __iter = __first + __begin; __iter < __first + __end; ++__iter) { if (!__binary_pred(*__iter, *(__iter - 1))) ++__i; } } __counter[__iam] = __i; // Last part still untouched. _DifferenceType __begin_output; # pragma omp barrier // Store result in output on calculated positions. __begin_output = 0; if (__iam == 0) { for (_ThreadIndex __t = 0; __t < __num_threads; ++__t) __begin_output += __counter[__t]; __i = 0; _OutputIterator __iter_out = __result + __begin_output; __begin = __borders[__num_threads]; __end = __size; for (_IIter __iter = __first + __begin; __iter < __first + __end; ++__iter) { if (__iter == __first || !__binary_pred(*__iter, *(__iter - 1))) { ++__i; *__iter_out++ = *__iter; } } __counter[__num_threads] = __i; } else { for (_ThreadIndex __t = 0; __t < __iam; __t++) __begin_output += __counter[__t]; _OutputIterator __iter_out = __result + __begin_output; for (_IIter __iter = __first + __begin; __iter < __first + __end; ++__iter) { if (!__binary_pred(*__iter, *(__iter - 1))) *__iter_out++ = *__iter; } } } _DifferenceType __end_output = 0; for (_ThreadIndex __t = 0; __t < __num_threads + 1; __t++) __end_output += __counter[__t]; delete[] __borders; return __result + __end_output; } /** @brief Parallel std::unique_copy(), without explicit equality predicate * @param __first Begin iterator of input sequence. * @param __last End iterator of input sequence. * @param __result Begin iterator of result __sequence. * @return End iterator of result __sequence. */ template inline _OutputIterator __parallel_unique_copy(_IIter __first, _IIter __last, _OutputIterator __result) { typedef typename std::iterator_traits<_IIter>::value_type _ValueType; return __parallel_unique_copy(__first, __last, __result, std::equal_to<_ValueType>()); } }//namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_UNIQUE_COPY_H */ 8/parallel/algorithm000064400000002545152526447520010442 0ustar00// Algorithm extensions -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/algorithm * This file is a GNU extension to the Standard C++ Library. */ #ifndef _PARALLEL_ALGORITHM #define _PARALLEL_ALGORITHM 1 #pragma GCC system_header #include #include #include #include #endif 8/parallel/random_number.h000064400000010203152526447520011520 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/random_number.h * @brief Random number generator based on the Mersenne twister. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_RANDOM_NUMBER_H #define _GLIBCXX_PARALLEL_RANDOM_NUMBER_H 1 #include #include #include namespace __gnu_parallel { /** @brief Random number generator, based on the Mersenne twister. */ class _RandomNumber { private: std::tr1::mt19937 _M_mt; uint64_t _M_supremum; uint64_t _M_rand_sup; double _M_supremum_reciprocal; double _M_rand_sup_reciprocal; // Assumed to be twice as long as the usual random number. uint64_t __cache; // Bit results. int __bits_left; static uint32_t __scale_down(uint64_t __x, #if _GLIBCXX_SCALE_DOWN_FPU uint64_t /*_M_supremum*/, double _M_supremum_reciprocal) #else uint64_t _M_supremum, double /*_M_supremum_reciprocal*/) #endif { #if _GLIBCXX_SCALE_DOWN_FPU return uint32_t(__x * _M_supremum_reciprocal); #else return static_cast(__x % _M_supremum); #endif } public: /** @brief Default constructor. Seed with 0. */ _RandomNumber() : _M_mt(0), _M_supremum(0x100000000ULL), _M_rand_sup(1ULL << std::numeric_limits::digits), _M_supremum_reciprocal(double(_M_supremum) / double(_M_rand_sup)), _M_rand_sup_reciprocal(1.0 / double(_M_rand_sup)), __cache(0), __bits_left(0) { } /** @brief Constructor. * @param __seed Random __seed. * @param _M_supremum Generate integer random numbers in the * interval @c [0,_M_supremum). */ _RandomNumber(uint32_t __seed, uint64_t _M_supremum = 0x100000000ULL) : _M_mt(__seed), _M_supremum(_M_supremum), _M_rand_sup(1ULL << std::numeric_limits::digits), _M_supremum_reciprocal(double(_M_supremum) / double(_M_rand_sup)), _M_rand_sup_reciprocal(1.0 / double(_M_rand_sup)), __cache(0), __bits_left(0) { } /** @brief Generate unsigned random 32-bit integer. */ uint32_t operator()() { return __scale_down(_M_mt(), _M_supremum, _M_supremum_reciprocal); } /** @brief Generate unsigned random 32-bit integer in the interval @c [0,local_supremum). */ uint32_t operator()(uint64_t local_supremum) { return __scale_down(_M_mt(), local_supremum, double(local_supremum * _M_rand_sup_reciprocal)); } /** @brief Generate a number of random bits, run-time parameter. * @param __bits Number of bits to generate. */ unsigned long __genrand_bits(int __bits) { unsigned long __res = __cache & ((1 << __bits) - 1); __cache = __cache >> __bits; __bits_left -= __bits; if (__bits_left < 32) { __cache |= ((uint64_t(_M_mt())) << __bits_left); __bits_left += 32; } return __res; } }; } // namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_RANDOM_NUMBER_H */ 8/parallel/for_each_selectors.h000064400000024505152526447520012533 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/for_each_selectors.h * @brief Functors representing different tasks to be plugged into the * generic parallelization methods for embarrassingly parallel functions. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H #define _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H 1 #include namespace __gnu_parallel { /** @brief Generic __selector for embarrassingly parallel functions. */ template struct __generic_for_each_selector { /** @brief _Iterator on last element processed; needed for some * algorithms (e. g. std::transform()). */ _It _M_finish_iterator; }; /** @brief std::for_each() selector. */ template struct __for_each_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ template bool operator()(_Op& __o, _It __i) { __o(*__i); return true; } }; /** @brief std::generate() selector. */ template struct __generate_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ template bool operator()(_Op& __o, _It __i) { *__i = __o(); return true; } }; /** @brief std::fill() selector. */ template struct __fill_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __v Current value. * @param __i iterator referencing object. */ template bool operator()(_ValueType& __v, _It __i) { *__i = __v; return true; } }; /** @brief std::transform() __selector, one input sequence variant. */ template struct __transform1_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ template bool operator()(_Op& __o, _It __i) { *__i.second = __o(*__i.first); return true; } }; /** @brief std::transform() __selector, two input sequences variant. */ template struct __transform2_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ template bool operator()(_Op& __o, _It __i) { *__i._M_third = __o(*__i._M_first, *__i._M_second); return true; } }; /** @brief std::replace() selector. */ template struct __replace_selector : public __generic_for_each_selector<_It> { /** @brief Value to replace with. */ const _Tp& __new_val; /** @brief Constructor * @param __new_val Value to replace with. */ explicit __replace_selector(const _Tp &__new_val) : __new_val(__new_val) {} /** @brief Functor execution. * @param __v Current value. * @param __i iterator referencing object. */ bool operator()(_Tp& __v, _It __i) { if (*__i == __v) *__i = __new_val; return true; } }; /** @brief std::replace() selector. */ template struct __replace_if_selector : public __generic_for_each_selector<_It> { /** @brief Value to replace with. */ const _Tp& __new_val; /** @brief Constructor. * @param __new_val Value to replace with. */ explicit __replace_if_selector(const _Tp &__new_val) : __new_val(__new_val) { } /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ bool operator()(_Op& __o, _It __i) { if (__o(*__i)) *__i = __new_val; return true; } }; /** @brief std::count() selector. */ template struct __count_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __v Current value. * @param __i iterator referencing object. * @return 1 if count, 0 if does not count. */ template _Diff operator()(_ValueType& __v, _It __i) { return (__v == *__i) ? 1 : 0; } }; /** @brief std::count_if () selector. */ template struct __count_if_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. * @return 1 if count, 0 if does not count. */ template _Diff operator()(_Op& __o, _It __i) { return (__o(*__i)) ? 1 : 0; } }; /** @brief std::accumulate() selector. */ template struct __accumulate_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator (unused). * @param __i iterator referencing object. * @return The current value. */ template typename std::iterator_traits<_It>::value_type operator()(_Op __o, _It __i) { return *__i; } }; /** @brief std::inner_product() selector. */ template struct __inner_product_selector : public __generic_for_each_selector<_It> { /** @brief Begin iterator of first sequence. */ _It __begin1_iterator; /** @brief Begin iterator of second sequence. */ _It2 __begin2_iterator; /** @brief Constructor. * @param __b1 Begin iterator of first sequence. * @param __b2 Begin iterator of second sequence. */ explicit __inner_product_selector(_It __b1, _It2 __b2) : __begin1_iterator(__b1), __begin2_iterator(__b2) { } /** @brief Functor execution. * @param __mult Multiplication functor. * @param __current iterator referencing object. * @return Inner product elemental __result. */ template _Tp operator()(_Op __mult, _It __current) { typename std::iterator_traits<_It>::difference_type __position = __current - __begin1_iterator; return __mult(*__current, *(__begin2_iterator + __position)); } }; /** @brief Selector that just returns the passed iterator. */ template struct __identity_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator (unused). * @param __i iterator referencing object. * @return Passed iterator. */ template _It operator()(_Op __o, _It __i) { return __i; } }; /** @brief Selector that returns the difference between two adjacent * __elements. */ template struct __adjacent_difference_selector : public __generic_for_each_selector<_It> { template bool operator()(_Op& __o, _It __i) { typename _It::first_type __go_back_one = __i.first; --__go_back_one; *__i.second = __o(*__i.first, *__go_back_one); return true; } }; /** @brief Functor doing nothing * * For some __reduction tasks (this is not a function object, but is * passed as __selector __dummy parameter. */ struct _Nothing { /** @brief Functor execution. * @param __i iterator referencing object. */ template void operator()(_It __i) { } }; /** @brief Reduction function doing nothing. */ struct _DummyReduct { bool operator()(bool, bool) const { return true; } }; /** @brief Reduction for finding the maximum element, using a comparator. */ template struct __min_element_reduct { _Compare& __comp; explicit __min_element_reduct(_Compare &__c) : __comp(__c) { } _It operator()(_It __x, _It __y) { return (__comp(*__x, *__y)) ? __x : __y; } }; /** @brief Reduction for finding the maximum element, using a comparator. */ template struct __max_element_reduct { _Compare& __comp; explicit __max_element_reduct(_Compare& __c) : __comp(__c) { } _It operator()(_It __x, _It __y) { return (__comp(*__x, *__y)) ? __y : __x; } }; /** @brief General reduction, using a binary operator. */ template struct __accumulate_binop_reduct { _BinOp& __binop; explicit __accumulate_binop_reduct(_BinOp& __b) : __binop(__b) { } template _Result operator()(const _Result& __x, const _Addend& __y) { return __binop(__x, __y); } }; } #endif /* _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H */ 8/parallel/find.h000064400000032427152526447520007624 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/find.h * @brief Parallel implementation base for std::find(), std::equal() * and related functions. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze and Johannes Singler. #ifndef _GLIBCXX_PARALLEL_FIND_H #define _GLIBCXX_PARALLEL_FIND_H 1 #include #include #include #include #include namespace __gnu_parallel { /** * @brief Parallel std::find, switch for different algorithms. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. Must have same * length as first sequence. * @param __pred Find predicate. * @param __selector _Functionality (e. g. std::find_if(), std::equal(),...) * @return Place of finding in both sequences. */ template inline std::pair<_RAIter1, _RAIter2> __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector) { switch (_Settings::get().find_algorithm) { case GROWING_BLOCKS: return __find_template(__begin1, __end1, __begin2, __pred, __selector, growing_blocks_tag()); case CONSTANT_SIZE_BLOCKS: return __find_template(__begin1, __end1, __begin2, __pred, __selector, constant_size_blocks_tag()); case EQUAL_SPLIT: return __find_template(__begin1, __end1, __begin2, __pred, __selector, equal_split_tag()); default: _GLIBCXX_PARALLEL_ASSERT(false); return std::make_pair(__begin1, __begin2); } } #if _GLIBCXX_FIND_EQUAL_SPLIT /** * @brief Parallel std::find, equal splitting variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. Second __sequence * must have same length as first sequence. * @param __pred Find predicate. * @param __selector _Functionality (e. g. std::find_if(), std::equal(),...) * @return Place of finding in both sequences. */ template std::pair<_RAIter1, _RAIter2> __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector, equal_split_tag) { _GLIBCXX_CALL(__end1 - __begin1) typedef std::iterator_traits<_RAIter1> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename _TraitsType::value_type _ValueType; _DifferenceType __length = __end1 - __begin1; _DifferenceType __result = __length; _DifferenceType* __borders; omp_lock_t __result_lock; omp_init_lock(&__result_lock); _ThreadIndex __num_threads = __get_max_threads(); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __borders = new _DifferenceType[__num_threads + 1]; __equally_split(__length, __num_threads, __borders); } //single _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __start = __borders[__iam], __stop = __borders[__iam + 1]; _RAIter1 __i1 = __begin1 + __start; _RAIter2 __i2 = __begin2 + __start; for (_DifferenceType __pos = __start; __pos < __stop; ++__pos) { # pragma omp flush(__result) // Result has been set to something lower. if (__result < __pos) break; if (__selector(__i1, __i2, __pred)) { omp_set_lock(&__result_lock); if (__pos < __result) __result = __pos; omp_unset_lock(&__result_lock); break; } ++__i1; ++__i2; } } //parallel omp_destroy_lock(&__result_lock); delete[] __borders; return std::pair<_RAIter1, _RAIter2>(__begin1 + __result, __begin2 + __result); } #endif #if _GLIBCXX_FIND_GROWING_BLOCKS /** * @brief Parallel std::find, growing block size variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. Second __sequence * must have same length as first sequence. * @param __pred Find predicate. * @param __selector _Functionality (e. g. std::find_if(), std::equal(),...) * @return Place of finding in both sequences. * @see __gnu_parallel::_Settings::find_sequential_search_size * @see __gnu_parallel::_Settings::find_scale_factor * * There are two main differences between the growing blocks and * the constant-size blocks variants. * 1. For GB, the block size grows; for CSB, the block size is fixed. * 2. For GB, the blocks are allocated dynamically; * for CSB, the blocks are allocated in a predetermined manner, * namely spacial round-robin. */ template std::pair<_RAIter1, _RAIter2> __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector, growing_blocks_tag) { _GLIBCXX_CALL(__end1 - __begin1) typedef std::iterator_traits<_RAIter1> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename _TraitsType::value_type _ValueType; const _Settings& __s = _Settings::get(); _DifferenceType __length = __end1 - __begin1; _DifferenceType __sequential_search_size = std::min<_DifferenceType> (__length, __s.find_sequential_search_size); // Try it sequentially first. std::pair<_RAIter1, _RAIter2> __find_seq_result = __selector._M_sequential_algorithm (__begin1, __begin1 + __sequential_search_size, __begin2, __pred); if (__find_seq_result.first != (__begin1 + __sequential_search_size)) return __find_seq_result; // Index of beginning of next free block (after sequential find). _DifferenceType __next_block_start = __sequential_search_size; _DifferenceType __result = __length; omp_lock_t __result_lock; omp_init_lock(&__result_lock); const float __scale_factor = __s.find_scale_factor; _ThreadIndex __num_threads = __get_max_threads(); # pragma omp parallel shared(__result) num_threads(__num_threads) { # pragma omp single __num_threads = omp_get_num_threads(); // Not within first __k elements -> start parallel. _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __block_size = std::max<_DifferenceType>(1, __scale_factor * __next_block_start); _DifferenceType __start = __fetch_and_add<_DifferenceType> (&__next_block_start, __block_size); // Get new block, update pointer to next block. _DifferenceType __stop = std::min<_DifferenceType>(__length, __start + __block_size); std::pair<_RAIter1, _RAIter2> __local_result; while (__start < __length) { # pragma omp flush(__result) // Get new value of result. if (__result < __start) { // No chance to find first element. break; } __local_result = __selector._M_sequential_algorithm (__begin1 + __start, __begin1 + __stop, __begin2 + __start, __pred); if (__local_result.first != (__begin1 + __stop)) { omp_set_lock(&__result_lock); if ((__local_result.first - __begin1) < __result) { __result = __local_result.first - __begin1; // Result cannot be in future blocks, stop algorithm. __fetch_and_add<_DifferenceType>(&__next_block_start, __length); } omp_unset_lock(&__result_lock); } _DifferenceType __block_size = std::max<_DifferenceType>(1, __scale_factor * __next_block_start); // Get new block, update pointer to next block. __start = __fetch_and_add<_DifferenceType>(&__next_block_start, __block_size); __stop = std::min<_DifferenceType>(__length, __start + __block_size); } } //parallel omp_destroy_lock(&__result_lock); // Return iterator on found element. return std::pair<_RAIter1, _RAIter2>(__begin1 + __result, __begin2 + __result); } #endif #if _GLIBCXX_FIND_CONSTANT_SIZE_BLOCKS /** * @brief Parallel std::find, constant block size variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. Second __sequence * must have same length as first sequence. * @param __pred Find predicate. * @param __selector _Functionality (e. g. std::find_if(), std::equal(),...) * @return Place of finding in both sequences. * @see __gnu_parallel::_Settings::find_sequential_search_size * @see __gnu_parallel::_Settings::find_block_size * There are two main differences between the growing blocks and the * constant-size blocks variants. * 1. For GB, the block size grows; for CSB, the block size is fixed. * 2. For GB, the blocks are allocated dynamically; for CSB, the * blocks are allocated in a predetermined manner, namely spacial * round-robin. */ template std::pair<_RAIter1, _RAIter2> __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector, constant_size_blocks_tag) { _GLIBCXX_CALL(__end1 - __begin1) typedef std::iterator_traits<_RAIter1> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename _TraitsType::value_type _ValueType; const _Settings& __s = _Settings::get(); _DifferenceType __length = __end1 - __begin1; _DifferenceType __sequential_search_size = std::min<_DifferenceType> (__length, __s.find_sequential_search_size); // Try it sequentially first. std::pair<_RAIter1, _RAIter2> __find_seq_result = __selector._M_sequential_algorithm (__begin1, __begin1 + __sequential_search_size, __begin2, __pred); if (__find_seq_result.first != (__begin1 + __sequential_search_size)) return __find_seq_result; _DifferenceType __result = __length; omp_lock_t __result_lock; omp_init_lock(&__result_lock); // Not within first __sequential_search_size elements -> start parallel. _ThreadIndex __num_threads = __get_max_threads(); # pragma omp parallel shared(__result) num_threads(__num_threads) { # pragma omp single __num_threads = omp_get_num_threads(); _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __block_size = __s.find_initial_block_size; // First element of thread's current iteration. _DifferenceType __iteration_start = __sequential_search_size; // Where to work (initialization). _DifferenceType __start = __iteration_start + __iam * __block_size; _DifferenceType __stop = std::min<_DifferenceType>(__length, __start + __block_size); std::pair<_RAIter1, _RAIter2> __local_result; while (__start < __length) { // Get new value of result. # pragma omp flush(__result) // No chance to find first element. if (__result < __start) break; __local_result = __selector._M_sequential_algorithm (__begin1 + __start, __begin1 + __stop, __begin2 + __start, __pred); if (__local_result.first != (__begin1 + __stop)) { omp_set_lock(&__result_lock); if ((__local_result.first - __begin1) < __result) __result = __local_result.first - __begin1; omp_unset_lock(&__result_lock); // Will not find better value in its interval. break; } __iteration_start += __num_threads * __block_size; // Where to work. __start = __iteration_start + __iam * __block_size; __stop = std::min<_DifferenceType>(__length, __start + __block_size); } } //parallel omp_destroy_lock(&__result_lock); // Return iterator on found element. return std::pair<_RAIter1, _RAIter2>(__begin1 + __result, __begin2 + __result); } #endif } // end namespace #endif /* _GLIBCXX_PARALLEL_FIND_H */ 8/parallel/list_partition.h000064400000014616152526447520011750 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute __it and/or modify __it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/list_partition.h * @brief _Functionality to split __sequence referenced by only input * iterators. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Leonor Frias Moya and Johannes Singler. #ifndef _GLIBCXX_PARALLEL_LIST_PARTITION_H #define _GLIBCXX_PARALLEL_LIST_PARTITION_H 1 #include #include namespace __gnu_parallel { /** @brief Shrinks and doubles the ranges. * @param __os_starts Start positions worked on (oversampled). * @param __count_to_two Counts up to 2. * @param __range_length Current length of a chunk. * @param __make_twice Whether the @c __os_starts is allowed to be * grown or not */ template void __shrink_and_double(std::vector<_IIter>& __os_starts, size_t& __count_to_two, size_t& __range_length, const bool __make_twice) { ++__count_to_two; if (!__make_twice || __count_to_two < 2) __shrink(__os_starts, __count_to_two, __range_length); else { __os_starts.resize((__os_starts.size() - 1) * 2 + 1); __count_to_two = 0; } } /** @brief Combines two ranges into one and thus halves the number of ranges. * @param __os_starts Start positions worked on (oversampled). * @param __count_to_two Counts up to 2. * @param __range_length Current length of a chunk. */ template void __shrink(std::vector<_IIter>& __os_starts, size_t& __count_to_two, size_t& __range_length) { for (typename std::vector<_IIter>::size_type __i = 0; __i <= (__os_starts.size() / 2); ++__i) __os_starts[__i] = __os_starts[__i * 2]; __range_length *= 2; } /** @brief Splits a sequence given by input iterators into parts of * almost equal size * * The function needs only one pass over the sequence. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __starts Start iterators for the resulting parts, dimension * @c __num_parts+1. For convenience, @c __starts @c [__num_parts] * contains the end iterator of the sequence. * @param __lengths Length of the resulting parts. * @param __num_parts Number of parts to split the sequence into. * @param __f Functor to be applied to each element by traversing __it * @param __oversampling Oversampling factor. If 0, then the * partitions will differ in at most * \f$\sqrt{\mathrm{end} - \mathrm{begin}}\f$ * elements. Otherwise, the ratio between the * longest and the shortest part is bounded by * \f$1/(\mathrm{oversampling} \cdot \mathrm{num\_parts})\f$ * @return Length of the whole sequence. */ template size_t list_partition(const _IIter __begin, const _IIter __end, _IIter* __starts, size_t* __lengths, const int __num_parts, _FunctorType& __f, int __oversampling = 0) { bool __make_twice = false; // The resizing algorithm is chosen according to the oversampling factor. if (__oversampling == 0) { __make_twice = true; __oversampling = 1; } std::vector<_IIter> __os_starts(2 * __oversampling * __num_parts + 1); __os_starts[0] = __begin; _IIter __prev = __begin, __it = __begin; size_t __dist_limit = 0, __dist = 0; size_t __cur = 1, __next = 1; size_t __range_length = 1; size_t __count_to_two = 0; while (__it != __end) { __cur = __next; for (; __cur < __os_starts.size() and __it != __end; ++__cur) { for (__dist_limit += __range_length; __dist < __dist_limit and __it != __end; ++__dist) { __f(__it); ++__it; } __os_starts[__cur] = __it; } // Must compare for end and not __cur < __os_starts.size() , because // __cur could be == __os_starts.size() as well if (__it == __end) break; __shrink_and_double(__os_starts, __count_to_two, __range_length, __make_twice); __next = __os_starts.size() / 2 + 1; } // Calculation of the parts (one must be extracted from __current // because the partition beginning at end, consists only of // itself). size_t __size_part = (__cur - 1) / __num_parts; int __size_greater = static_cast((__cur - 1) % __num_parts); __starts[0] = __os_starts[0]; size_t __index = 0; // Smallest partitions. for (int __i = 1; __i < (__num_parts + 1 - __size_greater); ++__i) { __lengths[__i - 1] = __size_part * __range_length; __index += __size_part; __starts[__i] = __os_starts[__index]; } // Biggest partitions. for (int __i = __num_parts + 1 - __size_greater; __i <= __num_parts; ++__i) { __lengths[__i - 1] = (__size_part+1) * __range_length; __index += (__size_part+1); __starts[__i] = __os_starts[__index]; } // Correction of the end size (the end iteration has not finished). __lengths[__num_parts - 1] -= (__dist_limit - __dist); return __dist; } } #endif /* _GLIBCXX_PARALLEL_LIST_PARTITION_H */ 8/parallel/algorithmfwd.h000064400000076716152526447520011404 0ustar00// Forward declarations -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/algorithmfwd.h * This file is a GNU parallel extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PARALLEL_ALGORITHMFWD_H #define _GLIBCXX_PARALLEL_ALGORITHMFWD_H 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { template _FIter adjacent_find(_FIter, _FIter); template _FIter adjacent_find(_FIter, _FIter, __gnu_parallel::sequential_tag); template _FIter __adjacent_find_switch(_FIter, _FIter, _IterTag); template _RAIter __adjacent_find_switch(_RAIter, _RAIter, random_access_iterator_tag); template _FIter adjacent_find(_FIter, _FIter, _BiPredicate); template _FIter adjacent_find(_FIter, _FIter, _BiPredicate, __gnu_parallel::sequential_tag); template _FIter __adjacent_find_switch(_FIter, _FIter, _BiPredicate, _IterTag); template _RAIter __adjacent_find_switch(_RAIter, _RAIter, _BiPredicate, random_access_iterator_tag); template typename iterator_traits<_IIter>::difference_type count(_IIter, _IIter, const _Tp&); template typename iterator_traits<_IIter>::difference_type count(_IIter, _IIter, const _Tp&, __gnu_parallel::sequential_tag); template typename iterator_traits<_IIter>::difference_type count(_IIter, _IIter, const _Tp&, __gnu_parallel::_Parallelism); template typename iterator_traits<_IIter>::difference_type __count_switch(_IIter, _IIter, const _Tp&, _IterTag); template typename iterator_traits<_RAIter>::difference_type __count_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_unbalanced); template typename iterator_traits<_IIter>::difference_type count_if(_IIter, _IIter, _Predicate); template typename iterator_traits<_IIter>::difference_type count_if(_IIter, _IIter, _Predicate, __gnu_parallel::sequential_tag); template typename iterator_traits<_IIter>::difference_type count_if(_IIter, _IIter, _Predicate, __gnu_parallel::_Parallelism); template typename iterator_traits<_IIter>::difference_type __count_if_switch(_IIter, _IIter, _Predicate, _IterTag); template typename iterator_traits<_RAIter>::difference_type __count_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_unbalanced); // algobase.h template bool equal(_IIter1, _IIter1, _IIter2, __gnu_parallel::sequential_tag); template bool equal(_IIter1, _IIter1, _IIter2, _Predicate, __gnu_parallel::sequential_tag); template bool equal(_IIter1, _IIter1, _IIter2); template bool equal(_IIter1, _IIter1, _IIter2, _Predicate); template _IIter find(_IIter, _IIter, const _Tp&, __gnu_parallel::sequential_tag); template _IIter find(_IIter, _IIter, const _Tp& __val); template _IIter __find_switch(_IIter, _IIter, const _Tp&, _IterTag); template _RAIter __find_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag); template _IIter find_if(_IIter, _IIter, _Predicate, __gnu_parallel::sequential_tag); template _IIter find_if(_IIter, _IIter, _Predicate); template _IIter __find_if_switch(_IIter, _IIter, _Predicate, _IterTag); template _RAIter __find_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag); template _IIter find_first_of(_IIter, _IIter, _FIter, _FIter, __gnu_parallel::sequential_tag); template _IIter find_first_of(_IIter, _IIter, _FIter, _FIter, _BiPredicate, __gnu_parallel::sequential_tag); template _IIter find_first_of(_IIter, _IIter, _FIter, _FIter, _BiPredicate); template _IIter find_first_of(_IIter, _IIter, _FIter, _FIter); template _IIter __find_first_of_switch( _IIter, _IIter, _FIter, _FIter, _IterTag1, _IterTag2); template _RAIter __find_first_of_switch(_RAIter, _RAIter, _FIter, _FIter, _BiPredicate, random_access_iterator_tag, _IterTag); template _IIter __find_first_of_switch(_IIter, _IIter, _FIter, _FIter, _BiPredicate, _IterTag1, _IterTag2); template _Function for_each(_IIter, _IIter, _Function); template _Function for_each(_IIter, _IIter, _Function, __gnu_parallel::sequential_tag); template _Function for_each(_Iterator, _Iterator, _Function, __gnu_parallel::_Parallelism); template _Function __for_each_switch(_IIter, _IIter, _Function, _IterTag); template _Function __for_each_switch(_RAIter, _RAIter, _Function, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template void generate(_FIter, _FIter, _Generator); template void generate(_FIter, _FIter, _Generator, __gnu_parallel::sequential_tag); template void generate(_FIter, _FIter, _Generator, __gnu_parallel::_Parallelism); template void __generate_switch(_FIter, _FIter, _Generator, _IterTag); template void __generate_switch(_RAIter, _RAIter, _Generator, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template _OIter generate_n(_OIter, _Size, _Generator); template _OIter generate_n(_OIter, _Size, _Generator, __gnu_parallel::sequential_tag); template _OIter generate_n(_OIter, _Size, _Generator, __gnu_parallel::_Parallelism); template _OIter __generate_n_switch(_OIter, _Size, _Generator, _IterTag); template _RAIter __generate_n_switch(_RAIter, _Size, _Generator, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, __gnu_parallel::sequential_tag); template bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Predicate, __gnu_parallel::sequential_tag); template bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2); template bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Predicate); template bool __lexicographical_compare_switch(_IIter1, _IIter1, _IIter2, _IIter2, _Predicate, _IterTag1, _IterTag2); template bool __lexicographical_compare_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Predicate, random_access_iterator_tag, random_access_iterator_tag); // algo.h template pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2, __gnu_parallel::sequential_tag); template pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2, _Predicate, __gnu_parallel::sequential_tag); template pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2); template pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2, _Predicate); template pair<_IIter1, _IIter2> __mismatch_switch(_IIter1, _IIter1, _IIter2, _Predicate, _IterTag1, _IterTag2); template pair<_RAIter1, _RAIter2> __mismatch_switch(_RAIter1, _RAIter1, _RAIter2, _Predicate, random_access_iterator_tag, random_access_iterator_tag); template _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2, __gnu_parallel::sequential_tag); template _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2); template _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate, __gnu_parallel::sequential_tag); template _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate); template _RAIter1 __search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, random_access_iterator_tag, random_access_iterator_tag); template _FIter1 __search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _IterTag1, _IterTag2); template _RAIter1 __search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _BiPredicate, random_access_iterator_tag, random_access_iterator_tag); template _FIter1 __search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate, _IterTag1, _IterTag2); template _FIter search_n(_FIter, _FIter, _Integer, const _Tp&, __gnu_parallel::sequential_tag); template _FIter search_n(_FIter, _FIter, _Integer, const _Tp&, _BiPredicate, __gnu_parallel::sequential_tag); template _FIter search_n(_FIter, _FIter, _Integer, const _Tp&); template _FIter search_n(_FIter, _FIter, _Integer, const _Tp&, _BiPredicate); template _RAIter __search_n_switch(_RAIter, _RAIter, _Integer, const _Tp&, _BiPredicate, random_access_iterator_tag); template _FIter __search_n_switch(_FIter, _FIter, _Integer, const _Tp&, _BiPredicate, _IterTag); template _OIter transform(_IIter, _IIter, _OIter, _UnaryOperation); template _OIter transform(_IIter, _IIter, _OIter, _UnaryOperation, __gnu_parallel::sequential_tag); template _OIter transform(_IIter, _IIter, _OIter, _UnaryOperation, __gnu_parallel::_Parallelism); template _OIter __transform1_switch(_IIter, _IIter, _OIter, _UnaryOperation, _IterTag1, _IterTag2); template _RAOIter __transform1_switch(_RAIIter, _RAIIter, _RAOIter, _UnaryOperation, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template _OIter transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation); template _OIter transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation, __gnu_parallel::sequential_tag); template _OIter transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation, __gnu_parallel::_Parallelism); template _RAIter3 __transform2_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter3, _BiOperation, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template _OIter __transform2_switch(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation, _Tag1, _Tag2, _Tag3); template void replace(_FIter, _FIter, const _Tp&, const _Tp&); template void replace(_FIter, _FIter, const _Tp&, const _Tp&, __gnu_parallel::sequential_tag); template void replace(_FIter, _FIter, const _Tp&, const _Tp&, __gnu_parallel::_Parallelism); template void __replace_switch(_FIter, _FIter, const _Tp&, const _Tp&, _IterTag); template void __replace_switch(_RAIter, _RAIter, const _Tp&, const _Tp&, random_access_iterator_tag, __gnu_parallel::_Parallelism); template void replace_if(_FIter, _FIter, _Predicate, const _Tp&); template void replace_if(_FIter, _FIter, _Predicate, const _Tp&, __gnu_parallel::sequential_tag); template void replace_if(_FIter, _FIter, _Predicate, const _Tp&, __gnu_parallel::_Parallelism); template void __replace_if_switch(_FIter, _FIter, _Predicate, const _Tp&, _IterTag); template void __replace_if_switch(_RAIter, _RAIter, _Predicate, const _Tp&, random_access_iterator_tag, __gnu_parallel::_Parallelism); template _FIter max_element(_FIter, _FIter); template _FIter max_element(_FIter, _FIter, __gnu_parallel::sequential_tag); template _FIter max_element(_FIter, _FIter, __gnu_parallel::_Parallelism); template _FIter max_element(_FIter, _FIter, _Compare); template _FIter max_element(_FIter, _FIter, _Compare, __gnu_parallel::sequential_tag); template _FIter max_element(_FIter, _FIter, _Compare, __gnu_parallel::_Parallelism); template _FIter __max_element_switch(_FIter, _FIter, _Compare, _IterTag); template _RAIter __max_element_switch( _RAIter, _RAIter, _Compare, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template _OIter merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template _OIter merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, __gnu_parallel::sequential_tag); template _OIter merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare); template _OIter merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template _OIter __merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, _IterTag1, _IterTag2, _IterTag3); template _OIter __merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template _FIter min_element(_FIter, _FIter); template _FIter min_element(_FIter, _FIter, __gnu_parallel::sequential_tag); template _FIter min_element(_FIter, _FIter, __gnu_parallel::_Parallelism __parallelism_tag); template _FIter min_element(_FIter, _FIter, _Compare); template _FIter min_element(_FIter, _FIter, _Compare, __gnu_parallel::sequential_tag); template _FIter min_element(_FIter, _FIter, _Compare, __gnu_parallel::_Parallelism); template _FIter __min_element_switch(_FIter, _FIter, _Compare, _IterTag); template _RAIter __min_element_switch( _RAIter, _RAIter, _Compare, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template void nth_element(_RAIter, _RAIter, _RAIter, __gnu_parallel::sequential_tag); template void nth_element(_RAIter, _RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag); template void nth_element(_RAIter, _RAIter, _RAIter, _Compare); template void nth_element(_RAIter, _RAIter, _RAIter); template void partial_sort(_RAIter, _RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag); template void partial_sort(_RAIter, _RAIter, _RAIter, __gnu_parallel::sequential_tag); template void partial_sort(_RAIter, _RAIter, _RAIter, _Compare); template void partial_sort(_RAIter, _RAIter, _RAIter); template _FIter partition(_FIter, _FIter, _Predicate, __gnu_parallel::sequential_tag); template _FIter partition(_FIter, _FIter, _Predicate); template _FIter __partition_switch(_FIter, _FIter, _Predicate, _IterTag); template _RAIter __partition_switch( _RAIter, _RAIter, _Predicate, random_access_iterator_tag); template void random_shuffle(_RAIter, _RAIter, __gnu_parallel::sequential_tag); template void random_shuffle(_RAIter, _RAIter, _RandomNumberGenerator&, __gnu_parallel::sequential_tag); template void random_shuffle(_RAIter, _RAIter); template void random_shuffle(_RAIter, _RAIter, #if __cplusplus >= 201103L _RandomNumberGenerator&&); #else _RandomNumberGenerator&); #endif template _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, __gnu_parallel::sequential_tag); template _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate); template _OIter __set_union_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3); template _Output_RAIter __set_union_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, __gnu_parallel::sequential_tag); template _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate); template _OIter __set_intersection_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3); template _Output_RAIter __set_intersection_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, __gnu_parallel::sequential_tag); template _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate); template _OIter __set_symmetric_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3); template _Output_RAIter __set_symmetric_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, __gnu_parallel::sequential_tag); template _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate); template _OIter __set_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3); template _Output_RAIter __set_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template void sort(_RAIter, _RAIter, __gnu_parallel::sequential_tag); template void sort(_RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag); template void sort(_RAIter, _RAIter); template void sort(_RAIter, _RAIter, _Compare); template void stable_sort(_RAIter, _RAIter, __gnu_parallel::sequential_tag); template void stable_sort(_RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag); template void stable_sort(_RAIter, _RAIter); template void stable_sort(_RAIter, _RAIter, _Compare); template _OIter unique_copy(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag); template _OIter unique_copy(_IIter, _IIter, _OIter, _Predicate, __gnu_parallel::sequential_tag); template _OIter unique_copy(_IIter, _IIter, _OIter); template _OIter unique_copy(_IIter, _IIter, _OIter, _Predicate); template _OIter __unique_copy_switch(_IIter, _IIter, _OIter, _Predicate, _IterTag1, _IterTag2); template _RandomAccess_OIter __unique_copy_switch(_RAIter, _RAIter, _RandomAccess_OIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag); } // end namespace __parallel } // end namespace std #endif /* _GLIBCXX_PARALLEL_ALGORITHMFWD_H */ 8/parallel/equally_split.h000064400000006434152526447520011572 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/equally_split.h * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H #define _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H 1 namespace __gnu_parallel { /** @brief function to split a sequence into parts of almost equal size. * * The resulting sequence __s of length __num_threads+1 contains the * splitting positions when splitting the range [0,__n) into parts of * almost equal size (plus minus 1). The first entry is 0, the last * one n. There may result empty parts. * @param __n Number of elements * @param __num_threads Number of parts * @param __s Splitters * @returns End of __splitter sequence, i.e. @c __s+__num_threads+1 */ template _OutputIterator __equally_split(_DifferenceType __n, _ThreadIndex __num_threads, _OutputIterator __s) { _DifferenceType __chunk_length = __n / __num_threads; _DifferenceType __num_longer_chunks = __n % __num_threads; _DifferenceType __pos = 0; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) { *__s++ = __pos; __pos += ((__i < __num_longer_chunks) ? (__chunk_length + 1) : __chunk_length); } *__s++ = __n; return __s; } /** @brief function to split a sequence into parts of almost equal size. * * Returns the position of the splitting point between * thread number __thread_no (included) and * thread number __thread_no+1 (excluded). * @param __n Number of elements * @param __num_threads Number of parts * @param __thread_no Number of threads * @returns splitting point */ template _DifferenceType __equally_split_point(_DifferenceType __n, _ThreadIndex __num_threads, _ThreadIndex __thread_no) { _DifferenceType __chunk_length = __n / __num_threads; _DifferenceType __num_longer_chunks = __n % __num_threads; if (__thread_no < __num_longer_chunks) return __thread_no * (__chunk_length + 1); else return __num_longer_chunks * (__chunk_length + 1) + (__thread_no - __num_longer_chunks) * __chunk_length; } } #endif /* _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H */ 8/parallel/queue.h000064400000012646152526447520010031 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/queue.h * @brief Lock-free double-ended queue. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_QUEUE_H #define _GLIBCXX_PARALLEL_QUEUE_H 1 #include #include #include /** @brief Decide whether to declare certain variable volatile in this file. */ #define _GLIBCXX_VOLATILE volatile namespace __gnu_parallel { /**@brief Double-ended queue of bounded size, allowing lock-free * atomic access. push_front() and pop_front() must not be called * concurrently to each other, while pop_back() can be called * concurrently at all times. * @c empty(), @c size(), and @c top() are intentionally not provided. * Calling them would not make sense in a concurrent setting. * @param _Tp Contained element type. */ template class _RestrictedBoundedConcurrentQueue { private: /** @brief Array of elements, seen as cyclic buffer. */ _Tp* _M_base; /** @brief Maximal number of elements contained at the same time. */ _SequenceIndex _M_max_size; /** @brief Cyclic __begin and __end pointers contained in one atomically changeable value. */ _GLIBCXX_VOLATILE _CASable _M_borders; public: /** @brief Constructor. Not to be called concurrent, of course. * @param __max_size Maximal number of elements to be contained. */ _RestrictedBoundedConcurrentQueue(_SequenceIndex __max_size) { _M_max_size = __max_size; _M_base = new _Tp[__max_size]; _M_borders = __encode2(0, 0); #pragma omp flush } /** @brief Destructor. Not to be called concurrent, of course. */ ~_RestrictedBoundedConcurrentQueue() { delete[] _M_base; } /** @brief Pushes one element into the queue at the front end. * Must not be called concurrently with pop_front(). */ void push_front(const _Tp& __t) { _CASable __former_borders = _M_borders; int __former_front, __former_back; __decode2(__former_borders, __former_front, __former_back); *(_M_base + __former_front % _M_max_size) = __t; #if _GLIBCXX_PARALLEL_ASSERTIONS // Otherwise: front - back > _M_max_size eventually. _GLIBCXX_PARALLEL_ASSERT(((__former_front + 1) - __former_back) <= _M_max_size); #endif __fetch_and_add(&_M_borders, __encode2(1, 0)); } /** @brief Pops one element from the queue at the front end. * Must not be called concurrently with pop_front(). */ bool pop_front(_Tp& __t) { int __former_front, __former_back; #pragma omp flush __decode2(_M_borders, __former_front, __former_back); while (__former_front > __former_back) { // Chance. _CASable __former_borders = __encode2(__former_front, __former_back); _CASable __new_borders = __encode2(__former_front - 1, __former_back); if (__compare_and_swap(&_M_borders, __former_borders, __new_borders)) { __t = *(_M_base + (__former_front - 1) % _M_max_size); return true; } #pragma omp flush __decode2(_M_borders, __former_front, __former_back); } return false; } /** @brief Pops one element from the queue at the front end. * Must not be called concurrently with pop_front(). */ bool pop_back(_Tp& __t) //queue behavior { int __former_front, __former_back; #pragma omp flush __decode2(_M_borders, __former_front, __former_back); while (__former_front > __former_back) { // Chance. _CASable __former_borders = __encode2(__former_front, __former_back); _CASable __new_borders = __encode2(__former_front, __former_back + 1); if (__compare_and_swap(&_M_borders, __former_borders, __new_borders)) { __t = *(_M_base + __former_back % _M_max_size); return true; } #pragma omp flush __decode2(_M_borders, __former_front, __former_back); } return false; } }; } //namespace __gnu_parallel #undef _GLIBCXX_VOLATILE #endif /* _GLIBCXX_PARALLEL_QUEUE_H */ 8/parallel/multiseq_selection.h000064400000053073152526447520012614 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/multiseq_selection.h * @brief Functions to find elements of a certain global __rank in * multiple sorted sequences. Also serves for splitting such * sequence sets. * * The algorithm description can be found in * * P. J. Varman, S. D. Scheufler, B. R. Iyer, and G. R. Ricard. * Merging Multiple Lists on Hierarchical-Memory Multiprocessors. * Journal of Parallel and Distributed Computing, 12(2):171–177, 1991. * * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H #define _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H 1 #include #include #include namespace __gnu_parallel { /** @brief Compare __a pair of types lexicographically, ascending. */ template class _Lexicographic : public std::binary_function, std::pair<_T1, _T2>, bool> { private: _Compare& _M_comp; public: _Lexicographic(_Compare& __comp) : _M_comp(__comp) { } bool operator()(const std::pair<_T1, _T2>& __p1, const std::pair<_T1, _T2>& __p2) const { if (_M_comp(__p1.first, __p2.first)) return true; if (_M_comp(__p2.first, __p1.first)) return false; // Firsts are equal. return __p1.second < __p2.second; } }; /** @brief Compare __a pair of types lexicographically, descending. */ template class _LexicographicReverse : public std::binary_function<_T1, _T2, bool> { private: _Compare& _M_comp; public: _LexicographicReverse(_Compare& __comp) : _M_comp(__comp) { } bool operator()(const std::pair<_T1, _T2>& __p1, const std::pair<_T1, _T2>& __p2) const { if (_M_comp(__p2.first, __p1.first)) return true; if (_M_comp(__p1.first, __p2.first)) return false; // Firsts are equal. return __p2.second < __p1.second; } }; /** * @brief Splits several sorted sequences at a certain global __rank, * resulting in a splitting point for each sequence. * The sequences are passed via a sequence of random-access * iterator pairs, none of the sequences may be empty. If there * are several equal elements across the split, the ones on the * __left side will be chosen from sequences with smaller number. * @param __begin_seqs Begin of the sequence of iterator pairs. * @param __end_seqs End of the sequence of iterator pairs. * @param __rank The global rank to partition at. * @param __begin_offsets A random-access __sequence __begin where the * __result will be stored in. Each element of the sequence is an * iterator that points to the first element on the greater part of * the respective __sequence. * @param __comp The ordering functor, defaults to std::less<_Tp>. */ template void multiseq_partition(_RanSeqs __begin_seqs, _RanSeqs __end_seqs, _RankType __rank, _RankIterator __begin_offsets, _Compare __comp = std::less< typename std::iterator_traits::value_type:: first_type>::value_type>()) // std::less<_Tp> { _GLIBCXX_CALL(__end_seqs - __begin_seqs) typedef typename std::iterator_traits<_RanSeqs>::value_type::first_type _It; typedef typename std::iterator_traits<_RanSeqs>::difference_type _SeqNumber; typedef typename std::iterator_traits<_It>::difference_type _DifferenceType; typedef typename std::iterator_traits<_It>::value_type _ValueType; _Lexicographic<_ValueType, _SeqNumber, _Compare> __lcomp(__comp); _LexicographicReverse<_ValueType, _SeqNumber, _Compare> __lrcomp(__comp); // Number of sequences, number of elements in total (possibly // including padding). _DifferenceType __m = std::distance(__begin_seqs, __end_seqs), __nn = 0, __nmax, __n, __r; for (_SeqNumber __i = 0; __i < __m; __i++) { __nn += std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second); _GLIBCXX_PARALLEL_ASSERT( std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second) > 0); } if (__rank == __nn) { for (_SeqNumber __i = 0; __i < __m; __i++) __begin_offsets[__i] = __begin_seqs[__i].second; // Very end. // Return __m - 1; return; } _GLIBCXX_PARALLEL_ASSERT(__m != 0); _GLIBCXX_PARALLEL_ASSERT(__nn != 0); _GLIBCXX_PARALLEL_ASSERT(__rank >= 0); _GLIBCXX_PARALLEL_ASSERT(__rank < __nn); _DifferenceType* __ns = new _DifferenceType[__m]; _DifferenceType* __a = new _DifferenceType[__m]; _DifferenceType* __b = new _DifferenceType[__m]; _DifferenceType __l; __ns[0] = std::distance(__begin_seqs[0].first, __begin_seqs[0].second); __nmax = __ns[0]; for (_SeqNumber __i = 0; __i < __m; __i++) { __ns[__i] = std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second); __nmax = std::max(__nmax, __ns[__i]); } __r = __rd_log2(__nmax) + 1; // Pad all lists to this length, at least as long as any ns[__i], // equality iff __nmax = 2^__k - 1. __l = (1ULL << __r) - 1; for (_SeqNumber __i = 0; __i < __m; __i++) { __a[__i] = 0; __b[__i] = __l; } __n = __l / 2; // Invariants: // 0 <= __a[__i] <= __ns[__i], 0 <= __b[__i] <= __l #define __S(__i) (__begin_seqs[__i].first) // Initial partition. std::vector > __sample; for (_SeqNumber __i = 0; __i < __m; __i++) if (__n < __ns[__i]) //__sequence long enough __sample.push_back(std::make_pair(__S(__i)[__n], __i)); __gnu_sequential::sort(__sample.begin(), __sample.end(), __lcomp); for (_SeqNumber __i = 0; __i < __m; __i++) //conceptual infinity if (__n >= __ns[__i]) //__sequence too short, conceptual infinity __sample.push_back( std::make_pair(__S(__i)[0] /*__dummy element*/, __i)); _DifferenceType __localrank = __rank / __l; _SeqNumber __j; for (__j = 0; __j < __localrank && ((__n + 1) <= __ns[__sample[__j].second]); ++__j) __a[__sample[__j].second] += __n + 1; for (; __j < __m; __j++) __b[__sample[__j].second] -= __n + 1; // Further refinement. while (__n > 0) { __n /= 2; _SeqNumber __lmax_seq = -1; // to avoid warning const _ValueType* __lmax = 0; // impossible to avoid the warning? for (_SeqNumber __i = 0; __i < __m; __i++) { if (__a[__i] > 0) { if (!__lmax) { __lmax = &(__S(__i)[__a[__i] - 1]); __lmax_seq = __i; } else { // Max, favor rear sequences. if (!__comp(__S(__i)[__a[__i] - 1], *__lmax)) { __lmax = &(__S(__i)[__a[__i] - 1]); __lmax_seq = __i; } } } } _SeqNumber __i; for (__i = 0; __i < __m; __i++) { _DifferenceType __middle = (__b[__i] + __a[__i]) / 2; if (__lmax && __middle < __ns[__i] && __lcomp(std::make_pair(__S(__i)[__middle], __i), std::make_pair(*__lmax, __lmax_seq))) __a[__i] = std::min(__a[__i] + __n + 1, __ns[__i]); else __b[__i] -= __n + 1; } _DifferenceType __leftsize = 0; for (_SeqNumber __i = 0; __i < __m; __i++) __leftsize += __a[__i] / (__n + 1); _DifferenceType __skew = __rank / (__n + 1) - __leftsize; if (__skew > 0) { // Move to the left, find smallest. std::priority_queue, std::vector >, _LexicographicReverse<_ValueType, _SeqNumber, _Compare> > __pq(__lrcomp); for (_SeqNumber __i = 0; __i < __m; __i++) if (__b[__i] < __ns[__i]) __pq.push(std::make_pair(__S(__i)[__b[__i]], __i)); for (; __skew != 0 && !__pq.empty(); --__skew) { _SeqNumber __source = __pq.top().second; __pq.pop(); __a[__source] = std::min(__a[__source] + __n + 1, __ns[__source]); __b[__source] += __n + 1; if (__b[__source] < __ns[__source]) __pq.push( std::make_pair(__S(__source)[__b[__source]], __source)); } } else if (__skew < 0) { // Move to the right, find greatest. std::priority_queue, std::vector >, _Lexicographic<_ValueType, _SeqNumber, _Compare> > __pq(__lcomp); for (_SeqNumber __i = 0; __i < __m; __i++) if (__a[__i] > 0) __pq.push(std::make_pair(__S(__i)[__a[__i] - 1], __i)); for (; __skew != 0; ++__skew) { _SeqNumber __source = __pq.top().second; __pq.pop(); __a[__source] -= __n + 1; __b[__source] -= __n + 1; if (__a[__source] > 0) __pq.push(std::make_pair( __S(__source)[__a[__source] - 1], __source)); } } } // Postconditions: // __a[__i] == __b[__i] in most cases, except when __a[__i] has been // clamped because of having reached the boundary // Now return the result, calculate the offset. // Compare the keys on both edges of the border. // Maximum of left edge, minimum of right edge. _ValueType* __maxleft = 0; _ValueType* __minright = 0; for (_SeqNumber __i = 0; __i < __m; __i++) { if (__a[__i] > 0) { if (!__maxleft) __maxleft = &(__S(__i)[__a[__i] - 1]); else { // Max, favor rear sequences. if (!__comp(__S(__i)[__a[__i] - 1], *__maxleft)) __maxleft = &(__S(__i)[__a[__i] - 1]); } } if (__b[__i] < __ns[__i]) { if (!__minright) __minright = &(__S(__i)[__b[__i]]); else { // Min, favor fore sequences. if (__comp(__S(__i)[__b[__i]], *__minright)) __minright = &(__S(__i)[__b[__i]]); } } } _SeqNumber __seq = 0; for (_SeqNumber __i = 0; __i < __m; __i++) __begin_offsets[__i] = __S(__i) + __a[__i]; delete[] __ns; delete[] __a; delete[] __b; } /** * @brief Selects the element at a certain global __rank from several * sorted sequences. * * The sequences are passed via a sequence of random-access * iterator pairs, none of the sequences may be empty. * @param __begin_seqs Begin of the sequence of iterator pairs. * @param __end_seqs End of the sequence of iterator pairs. * @param __rank The global rank to partition at. * @param __offset The rank of the selected element in the global * subsequence of elements equal to the selected element. If the * selected element is unique, this number is 0. * @param __comp The ordering functor, defaults to std::less. */ template _Tp multiseq_selection(_RanSeqs __begin_seqs, _RanSeqs __end_seqs, _RankType __rank, _RankType& __offset, _Compare __comp = std::less<_Tp>()) { _GLIBCXX_CALL(__end_seqs - __begin_seqs) typedef typename std::iterator_traits<_RanSeqs>::value_type::first_type _It; typedef typename std::iterator_traits<_RanSeqs>::difference_type _SeqNumber; typedef typename std::iterator_traits<_It>::difference_type _DifferenceType; _Lexicographic<_Tp, _SeqNumber, _Compare> __lcomp(__comp); _LexicographicReverse<_Tp, _SeqNumber, _Compare> __lrcomp(__comp); // Number of sequences, number of elements in total (possibly // including padding). _DifferenceType __m = std::distance(__begin_seqs, __end_seqs); _DifferenceType __nn = 0; _DifferenceType __nmax, __n, __r; for (_SeqNumber __i = 0; __i < __m; __i++) __nn += std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second); if (__m == 0 || __nn == 0 || __rank < 0 || __rank >= __nn) { // result undefined if there is no data or __rank is outside bounds throw std::exception(); } _DifferenceType* __ns = new _DifferenceType[__m]; _DifferenceType* __a = new _DifferenceType[__m]; _DifferenceType* __b = new _DifferenceType[__m]; _DifferenceType __l; __ns[0] = std::distance(__begin_seqs[0].first, __begin_seqs[0].second); __nmax = __ns[0]; for (_SeqNumber __i = 0; __i < __m; ++__i) { __ns[__i] = std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second); __nmax = std::max(__nmax, __ns[__i]); } __r = __rd_log2(__nmax) + 1; // Pad all lists to this length, at least as long as any ns[__i], // equality iff __nmax = 2^__k - 1 __l = __round_up_to_pow2(__r) - 1; for (_SeqNumber __i = 0; __i < __m; ++__i) { __a[__i] = 0; __b[__i] = __l; } __n = __l / 2; // Invariants: // 0 <= __a[__i] <= __ns[__i], 0 <= __b[__i] <= __l #define __S(__i) (__begin_seqs[__i].first) // Initial partition. std::vector > __sample; for (_SeqNumber __i = 0; __i < __m; __i++) if (__n < __ns[__i]) __sample.push_back(std::make_pair(__S(__i)[__n], __i)); __gnu_sequential::sort(__sample.begin(), __sample.end(), __lcomp, sequential_tag()); // Conceptual infinity. for (_SeqNumber __i = 0; __i < __m; __i++) if (__n >= __ns[__i]) __sample.push_back( std::make_pair(__S(__i)[0] /*__dummy element*/, __i)); _DifferenceType __localrank = __rank / __l; _SeqNumber __j; for (__j = 0; __j < __localrank && ((__n + 1) <= __ns[__sample[__j].second]); ++__j) __a[__sample[__j].second] += __n + 1; for (; __j < __m; ++__j) __b[__sample[__j].second] -= __n + 1; // Further refinement. while (__n > 0) { __n /= 2; const _Tp* __lmax = 0; for (_SeqNumber __i = 0; __i < __m; ++__i) { if (__a[__i] > 0) { if (!__lmax) __lmax = &(__S(__i)[__a[__i] - 1]); else { if (__comp(*__lmax, __S(__i)[__a[__i] - 1])) //max __lmax = &(__S(__i)[__a[__i] - 1]); } } } _SeqNumber __i; for (__i = 0; __i < __m; __i++) { _DifferenceType __middle = (__b[__i] + __a[__i]) / 2; if (__lmax && __middle < __ns[__i] && __comp(__S(__i)[__middle], *__lmax)) __a[__i] = std::min(__a[__i] + __n + 1, __ns[__i]); else __b[__i] -= __n + 1; } _DifferenceType __leftsize = 0; for (_SeqNumber __i = 0; __i < __m; ++__i) __leftsize += __a[__i] / (__n + 1); _DifferenceType __skew = __rank / (__n + 1) - __leftsize; if (__skew > 0) { // Move to the left, find smallest. std::priority_queue, std::vector >, _LexicographicReverse<_Tp, _SeqNumber, _Compare> > __pq(__lrcomp); for (_SeqNumber __i = 0; __i < __m; ++__i) if (__b[__i] < __ns[__i]) __pq.push(std::make_pair(__S(__i)[__b[__i]], __i)); for (; __skew != 0 && !__pq.empty(); --__skew) { _SeqNumber __source = __pq.top().second; __pq.pop(); __a[__source] = std::min(__a[__source] + __n + 1, __ns[__source]); __b[__source] += __n + 1; if (__b[__source] < __ns[__source]) __pq.push( std::make_pair(__S(__source)[__b[__source]], __source)); } } else if (__skew < 0) { // Move to the right, find greatest. std::priority_queue, std::vector >, _Lexicographic<_Tp, _SeqNumber, _Compare> > __pq(__lcomp); for (_SeqNumber __i = 0; __i < __m; ++__i) if (__a[__i] > 0) __pq.push(std::make_pair(__S(__i)[__a[__i] - 1], __i)); for (; __skew != 0; ++__skew) { _SeqNumber __source = __pq.top().second; __pq.pop(); __a[__source] -= __n + 1; __b[__source] -= __n + 1; if (__a[__source] > 0) __pq.push(std::make_pair( __S(__source)[__a[__source] - 1], __source)); } } } // Postconditions: // __a[__i] == __b[__i] in most cases, except when __a[__i] has been // clamped because of having reached the boundary // Now return the result, calculate the offset. // Compare the keys on both edges of the border. // Maximum of left edge, minimum of right edge. bool __maxleftset = false, __minrightset = false; // Impossible to avoid the warning? _Tp __maxleft, __minright; for (_SeqNumber __i = 0; __i < __m; ++__i) { if (__a[__i] > 0) { if (!__maxleftset) { __maxleft = __S(__i)[__a[__i] - 1]; __maxleftset = true; } else { // Max. if (__comp(__maxleft, __S(__i)[__a[__i] - 1])) __maxleft = __S(__i)[__a[__i] - 1]; } } if (__b[__i] < __ns[__i]) { if (!__minrightset) { __minright = __S(__i)[__b[__i]]; __minrightset = true; } else { // Min. if (__comp(__S(__i)[__b[__i]], __minright)) __minright = __S(__i)[__b[__i]]; } } } // Minright is the __splitter, in any case. if (!__maxleftset || __comp(__minright, __maxleft)) { // Good luck, everything is split unambiguously. __offset = 0; } else { // We have to calculate an offset. __offset = 0; for (_SeqNumber __i = 0; __i < __m; ++__i) { _DifferenceType lb = std::lower_bound(__S(__i), __S(__i) + __ns[__i], __minright, __comp) - __S(__i); __offset += __a[__i] - lb; } } delete[] __ns; delete[] __a; delete[] __b; return __minright; } } #undef __S #endif /* _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H */ 8/parallel/sort.h000064400000017035152526447520007671 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/sort.h * @brief Parallel sorting algorithm switch. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_SORT_H #define _GLIBCXX_PARALLEL_SORT_H 1 #include #include #include #if _GLIBCXX_PARALLEL_ASSERTIONS #include #endif #if _GLIBCXX_MERGESORT #include #endif #if _GLIBCXX_QUICKSORT #include #endif #if _GLIBCXX_BAL_QUICKSORT #include #endif namespace __gnu_parallel { //prototype template void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, _Parallelism __parallelism); /** * @brief Choose multiway mergesort, splitting variant at run-time, * for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, multiway_mergesort_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) if(_Settings::get().sort_splitting == EXACT) parallel_sort_mwms<__stable, true> (__begin, __end, __comp, __parallelism.__get_num_threads()); else parallel_sort_mwms<__stable, false> (__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose multiway mergesort with exact splitting, * for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, multiway_mergesort_exact_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) parallel_sort_mwms<__stable, true> (__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose multiway mergesort with splitting by sampling, * for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, multiway_mergesort_sampling_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) parallel_sort_mwms<__stable, false> (__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose quicksort for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, quicksort_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) _GLIBCXX_PARALLEL_ASSERT(__stable == false); __parallel_sort_qs(__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose balanced quicksort for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, balanced_quicksort_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) _GLIBCXX_PARALLEL_ASSERT(__stable == false); __parallel_sort_qsb(__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose multiway mergesort with exact splitting, * for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, default_parallel_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) __parallel_sort<__stable> (__begin, __end, __comp, multiway_mergesort_exact_tag(__parallelism.__get_num_threads())); } /** * @brief Choose a parallel sorting algorithm. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, parallel_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; if (false) ; #if _GLIBCXX_MERGESORT else if (__stable || _Settings::get().sort_algorithm == MWMS) { if(_Settings::get().sort_splitting == EXACT) parallel_sort_mwms<__stable, true> (__begin, __end, __comp, __parallelism.__get_num_threads()); else parallel_sort_mwms (__begin, __end, __comp, __parallelism.__get_num_threads()); } #endif #if _GLIBCXX_QUICKSORT else if (_Settings::get().sort_algorithm == QS) __parallel_sort_qs(__begin, __end, __comp, __parallelism.__get_num_threads()); #endif #if _GLIBCXX_BAL_QUICKSORT else if (_Settings::get().sort_algorithm == QS_BALANCED) __parallel_sort_qsb(__begin, __end, __comp, __parallelism.__get_num_threads()); #endif else __gnu_sequential::sort(__begin, __end, __comp); } } // end namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_SORT_H */ 8/parallel/multiway_mergesort.h000064400000035647152526447520012655 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/multiway_mergesort.h * @brief Parallel multiway merge sort. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H #define _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H 1 #include #include #include #include #include namespace __gnu_parallel { /** @brief Subsequence description. */ template struct _Piece { typedef _DifferenceTp _DifferenceType; /** @brief Begin of subsequence. */ _DifferenceType _M_begin; /** @brief End of subsequence. */ _DifferenceType _M_end; }; /** @brief Data accessed by all threads. * * PMWMS = parallel multiway mergesort */ template struct _PMWMSSortingData { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; /** @brief Number of threads involved. */ _ThreadIndex _M_num_threads; /** @brief Input __begin. */ _RAIter _M_source; /** @brief Start indices, per thread. */ _DifferenceType* _M_starts; /** @brief Storage in which to sort. */ _ValueType** _M_temporary; /** @brief Samples. */ _ValueType* _M_samples; /** @brief Offsets to add to the found positions. */ _DifferenceType* _M_offsets; /** @brief Pieces of data to merge @c [thread][__sequence] */ std::vector<_Piece<_DifferenceType> >* _M_pieces; }; /** * @brief Select _M_samples from a sequence. * @param __sd Pointer to algorithm data. _Result will be placed in * @c __sd->_M_samples. * @param __num_samples Number of _M_samples to select. */ template void __determine_samples(_PMWMSSortingData<_RAIter>* __sd, _DifferenceTp __num_samples) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef _DifferenceTp _DifferenceType; _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType* __es = new _DifferenceType[__num_samples + 2]; __equally_split(__sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam], __num_samples + 1, __es); for (_DifferenceType __i = 0; __i < __num_samples; ++__i) ::new(&(__sd->_M_samples[__iam * __num_samples + __i])) _ValueType(__sd->_M_source[__sd->_M_starts[__iam] + __es[__i + 1]]); delete[] __es; } /** @brief Split consistently. */ template struct _SplitConsistently { }; /** @brief Split by exact splitting. */ template struct _SplitConsistently { void operator()(const _ThreadIndex __iam, _PMWMSSortingData<_RAIter>* __sd, _Compare& __comp, const typename std::iterator_traits<_RAIter>::difference_type __num_samples) const { # pragma omp barrier std::vector > __seqs(__sd->_M_num_threads); for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; __s++) __seqs[__s] = std::make_pair(__sd->_M_temporary[__s], __sd->_M_temporary[__s] + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s])); std::vector<_SortingPlacesIterator> __offsets(__sd->_M_num_threads); // if not last thread if (__iam < __sd->_M_num_threads - 1) multiseq_partition(__seqs.begin(), __seqs.end(), __sd->_M_starts[__iam + 1], __offsets.begin(), __comp); for (_ThreadIndex __seq = 0; __seq < __sd->_M_num_threads; __seq++) { // for each sequence if (__iam < (__sd->_M_num_threads - 1)) __sd->_M_pieces[__iam][__seq]._M_end = __offsets[__seq] - __seqs[__seq].first; else // very end of this sequence __sd->_M_pieces[__iam][__seq]._M_end = __sd->_M_starts[__seq + 1] - __sd->_M_starts[__seq]; } # pragma omp barrier for (_ThreadIndex __seq = 0; __seq < __sd->_M_num_threads; __seq++) { // For each sequence. if (__iam > 0) __sd->_M_pieces[__iam][__seq]._M_begin = __sd->_M_pieces[__iam - 1][__seq]._M_end; else // Absolute beginning. __sd->_M_pieces[__iam][__seq]._M_begin = 0; } } }; /** @brief Split by sampling. */ template struct _SplitConsistently { void operator()(const _ThreadIndex __iam, _PMWMSSortingData<_RAIter>* __sd, _Compare& __comp, const typename std::iterator_traits<_RAIter>::difference_type __num_samples) const { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; __determine_samples(__sd, __num_samples); # pragma omp barrier # pragma omp single __gnu_sequential::sort(__sd->_M_samples, __sd->_M_samples + (__num_samples * __sd->_M_num_threads), __comp); # pragma omp barrier for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; ++__s) { // For each sequence. if (__num_samples * __iam > 0) __sd->_M_pieces[__iam][__s]._M_begin = std::lower_bound(__sd->_M_temporary[__s], __sd->_M_temporary[__s] + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]), __sd->_M_samples[__num_samples * __iam], __comp) - __sd->_M_temporary[__s]; else // Absolute beginning. __sd->_M_pieces[__iam][__s]._M_begin = 0; if ((__num_samples * (__iam + 1)) < (__num_samples * __sd->_M_num_threads)) __sd->_M_pieces[__iam][__s]._M_end = std::lower_bound(__sd->_M_temporary[__s], __sd->_M_temporary[__s] + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]), __sd->_M_samples[__num_samples * (__iam + 1)], __comp) - __sd->_M_temporary[__s]; else // Absolute end. __sd->_M_pieces[__iam][__s]._M_end = (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]); } } }; template struct __possibly_stable_sort { }; template struct __possibly_stable_sort { void operator()(const _RAIter& __begin, const _RAIter& __end, _Compare& __comp) const { __gnu_sequential::stable_sort(__begin, __end, __comp); } }; template struct __possibly_stable_sort { void operator()(const _RAIter __begin, const _RAIter __end, _Compare& __comp) const { __gnu_sequential::sort(__begin, __end, __comp); } }; template struct __possibly_stable_multiway_merge { }; template struct __possibly_stable_multiway_merge { void operator()(const Seq_RAIter& __seqs_begin, const Seq_RAIter& __seqs_end, const _RAIter& __target, _Compare& __comp, _DiffType __length_am) const { stable_multiway_merge(__seqs_begin, __seqs_end, __target, __length_am, __comp, sequential_tag()); } }; template struct __possibly_stable_multiway_merge { void operator()(const Seq_RAIter& __seqs_begin, const Seq_RAIter& __seqs_end, const _RAIter& __target, _Compare& __comp, _DiffType __length_am) const { multiway_merge(__seqs_begin, __seqs_end, __target, __length_am, __comp, sequential_tag()); } }; /** @brief PMWMS code executed by each thread. * @param __sd Pointer to algorithm data. * @param __comp Comparator. */ template void parallel_sort_mwms_pu(_PMWMSSortingData<_RAIter>* __sd, _Compare& __comp) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _ThreadIndex __iam = omp_get_thread_num(); // Length of this thread's chunk, before merging. _DifferenceType __length_local = __sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam]; // Sort in temporary storage, leave space for sentinel. typedef _ValueType* _SortingPlacesIterator; __sd->_M_temporary[__iam] = static_cast<_ValueType*>(::operator new(sizeof(_ValueType) * (__length_local + 1))); // Copy there. std::uninitialized_copy(__sd->_M_source + __sd->_M_starts[__iam], __sd->_M_source + __sd->_M_starts[__iam] + __length_local, __sd->_M_temporary[__iam]); __possibly_stable_sort<__stable, _SortingPlacesIterator, _Compare>() (__sd->_M_temporary[__iam], __sd->_M_temporary[__iam] + __length_local, __comp); // Invariant: locally sorted subsequence in sd->_M_temporary[__iam], // __sd->_M_temporary[__iam] + __length_local. // No barrier here: Synchronization is done by the splitting routine. _DifferenceType __num_samples = _Settings::get().sort_mwms_oversampling * __sd->_M_num_threads - 1; _SplitConsistently<__exact, _RAIter, _Compare, _SortingPlacesIterator>() (__iam, __sd, __comp, __num_samples); // Offset from __target __begin, __length after merging. _DifferenceType __offset = 0, __length_am = 0; for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; __s++) { __length_am += (__sd->_M_pieces[__iam][__s]._M_end - __sd->_M_pieces[__iam][__s]._M_begin); __offset += __sd->_M_pieces[__iam][__s]._M_begin; } typedef std::vector< std::pair<_SortingPlacesIterator, _SortingPlacesIterator> > _SeqVector; _SeqVector __seqs(__sd->_M_num_threads); for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; ++__s) { __seqs[__s] = std::make_pair(__sd->_M_temporary[__s] + __sd->_M_pieces[__iam][__s]._M_begin, __sd->_M_temporary[__s] + __sd->_M_pieces[__iam][__s]._M_end); } __possibly_stable_multiway_merge< __stable, typename _SeqVector::iterator, _RAIter, _Compare, _DifferenceType>()(__seqs.begin(), __seqs.end(), __sd->_M_source + __offset, __comp, __length_am); # pragma omp barrier for (_DifferenceType __i = 0; __i < __length_local; ++__i) __sd->_M_temporary[__iam][__i].~_ValueType(); ::operator delete(__sd->_M_temporary[__iam]); } /** @brief PMWMS main call. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __comp Comparator. * @param __num_threads Number of threads to use. */ template void parallel_sort_mwms(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { _GLIBCXX_CALL(__end - __begin) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; if (__n <= 1) return; // at least one element per thread if (__num_threads > __n) __num_threads = static_cast<_ThreadIndex>(__n); // shared variables _PMWMSSortingData<_RAIter> __sd; _DifferenceType* __starts; _DifferenceType __size; # pragma omp parallel num_threads(__num_threads) { __num_threads = omp_get_num_threads(); //no more threads than requested # pragma omp single { __sd._M_num_threads = __num_threads; __sd._M_source = __begin; __sd._M_temporary = new _ValueType*[__num_threads]; if (!__exact) { __size = (_Settings::get().sort_mwms_oversampling * __num_threads - 1) * __num_threads; __sd._M_samples = static_cast<_ValueType*> (::operator new(__size * sizeof(_ValueType))); } else __sd._M_samples = 0; __sd._M_offsets = new _DifferenceType[__num_threads - 1]; __sd._M_pieces = new std::vector<_Piece<_DifferenceType> >[__num_threads]; for (_ThreadIndex __s = 0; __s < __num_threads; ++__s) __sd._M_pieces[__s].resize(__num_threads); __starts = __sd._M_starts = new _DifferenceType[__num_threads + 1]; _DifferenceType __chunk_length = __n / __num_threads; _DifferenceType __split = __n % __num_threads; _DifferenceType __pos = 0; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) { __starts[__i] = __pos; __pos += ((__i < __split) ? (__chunk_length + 1) : __chunk_length); } __starts[__num_threads] = __pos; } //single // Now sort in parallel. parallel_sort_mwms_pu<__stable, __exact>(&__sd, __comp); } //parallel delete[] __starts; delete[] __sd._M_temporary; if (!__exact) { for (_DifferenceType __i = 0; __i < __size; ++__i) __sd._M_samples[__i].~_ValueType(); ::operator delete(__sd._M_samples); } delete[] __sd._M_offsets; delete[] __sd._M_pieces; } } //namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H */ 8/parallel/settings.h000064400000030252152526447520010536 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/settings.h * @brief Runtime settings and tuning parameters, heuristics to decide * whether to use parallelized algorithms. * This file is a GNU parallel extension to the Standard C++ Library. * * @section parallelization_decision * The decision whether to run an algorithm in parallel. * * There are several ways the user can switch on and __off the parallel * execution of an algorithm, both at compile- and run-time. * * Only sequential execution can be forced at compile-time. This * reduces code size and protects code parts that have * non-thread-safe side effects. * * Ultimately, forcing parallel execution at compile-time makes * sense. Often, the sequential algorithm implementation is used as * a subroutine, so no reduction in code size can be achieved. Also, * the machine the program is run on might have only one processor * core, so to avoid overhead, the algorithm is executed * sequentially. * * To force sequential execution of an algorithm ultimately at * compile-time, the user must add the tag * gnu_parallel::sequential_tag() to the end of the parameter list, * e. g. * * \code * std::sort(__v.begin(), __v.end(), __gnu_parallel::sequential_tag()); * \endcode * * This is compatible with all overloaded algorithm variants. No * additional code will be instantiated, at all. The same holds for * most algorithm calls with iterators not providing random access. * * If the algorithm call is not forced to be executed sequentially * at compile-time, the decision is made at run-time. * The global variable __gnu_parallel::_Settings::algorithm_strategy * is checked. _It is a tristate variable corresponding to: * * a. force_sequential, meaning the sequential algorithm is executed. * b. force_parallel, meaning the parallel algorithm is executed. * c. heuristic * * For heuristic, the parallel algorithm implementation is called * only if the input size is sufficiently large. For most * algorithms, the input size is the (combined) length of the input * sequence(__s). The threshold can be set by the user, individually * for each algorithm. The according variables are called * gnu_parallel::_Settings::[algorithm]_minimal_n . * * For some of the algorithms, there are even more tuning options, * e. g. the ability to choose from multiple algorithm variants. See * below for details. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_SETTINGS_H #define _GLIBCXX_PARALLEL_SETTINGS_H 1 #include /** * @brief Determine at compile(?)-time if the parallel variant of an * algorithm should be called. * @param __c A condition that is convertible to bool that is overruled by * __gnu_parallel::_Settings::algorithm_strategy. Usually a decision * based on the input size. */ #define _GLIBCXX_PARALLEL_CONDITION(__c) \ (__gnu_parallel::_Settings::get().algorithm_strategy \ != __gnu_parallel::force_sequential \ && ((__gnu_parallel::__get_max_threads() > 1 && (__c)) \ || __gnu_parallel::_Settings::get().algorithm_strategy \ == __gnu_parallel::force_parallel)) /* inline bool parallel_condition(bool __c) { bool ret = false; const _Settings& __s = _Settings::get(); if (__s.algorithm_strategy != force_seqential) { if (__s.algorithm_strategy == force_parallel) ret = true; else ret = __get_max_threads() > 1 && __c; } return ret; } */ namespace __gnu_parallel { /// class _Settings /// Run-time settings for the parallel mode including all tunable parameters. struct _Settings { _AlgorithmStrategy algorithm_strategy; _SortAlgorithm sort_algorithm; _PartialSumAlgorithm partial_sum_algorithm; _MultiwayMergeAlgorithm multiway_merge_algorithm; _FindAlgorithm find_algorithm; _SplittingAlgorithm sort_splitting; _SplittingAlgorithm merge_splitting; _SplittingAlgorithm multiway_merge_splitting; // Per-algorithm settings. /// Minimal input size for accumulate. _SequenceIndex accumulate_minimal_n; /// Minimal input size for adjacent_difference. unsigned int adjacent_difference_minimal_n; /// Minimal input size for count and count_if. _SequenceIndex count_minimal_n; /// Minimal input size for fill. _SequenceIndex fill_minimal_n; /// Block size increase factor for find. double find_increasing_factor; /// Initial block size for find. _SequenceIndex find_initial_block_size; /// Maximal block size for find. _SequenceIndex find_maximum_block_size; /// Start with looking for this many elements sequentially, for find. _SequenceIndex find_sequential_search_size; /// Minimal input size for for_each. _SequenceIndex for_each_minimal_n; /// Minimal input size for generate. _SequenceIndex generate_minimal_n; /// Minimal input size for max_element. _SequenceIndex max_element_minimal_n; /// Minimal input size for merge. _SequenceIndex merge_minimal_n; /// Oversampling factor for merge. unsigned int merge_oversampling; /// Minimal input size for min_element. _SequenceIndex min_element_minimal_n; /// Minimal input size for multiway_merge. _SequenceIndex multiway_merge_minimal_n; /// Oversampling factor for multiway_merge. int multiway_merge_minimal_k; /// Oversampling factor for multiway_merge. unsigned int multiway_merge_oversampling; /// Minimal input size for nth_element. _SequenceIndex nth_element_minimal_n; /// Chunk size for partition. _SequenceIndex partition_chunk_size; /// Chunk size for partition, relative to input size. If > 0.0, /// this value overrides partition_chunk_size. double partition_chunk_share; /// Minimal input size for partition. _SequenceIndex partition_minimal_n; /// Minimal input size for partial_sort. _SequenceIndex partial_sort_minimal_n; /// Ratio for partial_sum. Assume "sum and write result" to be /// this factor slower than just "sum". float partial_sum_dilation; /// Minimal input size for partial_sum. unsigned int partial_sum_minimal_n; /// Minimal input size for random_shuffle. unsigned int random_shuffle_minimal_n; /// Minimal input size for replace and replace_if. _SequenceIndex replace_minimal_n; /// Minimal input size for set_difference. _SequenceIndex set_difference_minimal_n; /// Minimal input size for set_intersection. _SequenceIndex set_intersection_minimal_n; /// Minimal input size for set_symmetric_difference. _SequenceIndex set_symmetric_difference_minimal_n; /// Minimal input size for set_union. _SequenceIndex set_union_minimal_n; /// Minimal input size for parallel sorting. _SequenceIndex sort_minimal_n; /// Oversampling factor for parallel std::sort (MWMS). unsigned int sort_mwms_oversampling; /// Such many samples to take to find a good pivot (quicksort). unsigned int sort_qs_num_samples_preset; /// Maximal subsequence __length to switch to unbalanced __base case. /// Applies to std::sort with dynamically load-balanced quicksort. _SequenceIndex sort_qsb_base_case_maximal_n; /// Minimal input size for parallel std::transform. _SequenceIndex transform_minimal_n; /// Minimal input size for unique_copy. _SequenceIndex unique_copy_minimal_n; _SequenceIndex workstealing_chunk_size; // Hardware dependent tuning parameters. /// size of the L1 cache in bytes (underestimation). unsigned long long L1_cache_size; /// size of the L2 cache in bytes (underestimation). unsigned long long L2_cache_size; /// size of the Translation Lookaside Buffer (underestimation). unsigned int TLB_size; /// Overestimation of cache line size. Used to avoid false /// sharing, i.e. elements of different threads are at least this /// amount apart. unsigned int cache_line_size; // Statistics. /// The number of stolen ranges in load-balanced quicksort. _SequenceIndex qsb_steals; /// Minimal input size for search and search_n. _SequenceIndex search_minimal_n; /// Block size scale-down factor with respect to current position. float find_scale_factor; /// Get the global settings. _GLIBCXX_CONST static const _Settings& get() throw(); /// Set the global settings. static void set(_Settings&) throw(); explicit _Settings() : algorithm_strategy(heuristic), sort_algorithm(MWMS), partial_sum_algorithm(LINEAR), multiway_merge_algorithm(LOSER_TREE), find_algorithm(CONSTANT_SIZE_BLOCKS), sort_splitting(EXACT), merge_splitting(EXACT), multiway_merge_splitting(EXACT), accumulate_minimal_n(1000), adjacent_difference_minimal_n(1000), count_minimal_n(1000), fill_minimal_n(1000), find_increasing_factor(2.0), find_initial_block_size(256), find_maximum_block_size(8192), find_sequential_search_size(256), for_each_minimal_n(1000), generate_minimal_n(1000), max_element_minimal_n(1000), merge_minimal_n(1000), merge_oversampling(10), min_element_minimal_n(1000), multiway_merge_minimal_n(1000), multiway_merge_minimal_k(2), multiway_merge_oversampling(10), nth_element_minimal_n(1000), partition_chunk_size(1000), partition_chunk_share(0.0), partition_minimal_n(1000), partial_sort_minimal_n(1000), partial_sum_dilation(1.0f), partial_sum_minimal_n(1000), random_shuffle_minimal_n(1000), replace_minimal_n(1000), set_difference_minimal_n(1000), set_intersection_minimal_n(1000), set_symmetric_difference_minimal_n(1000), set_union_minimal_n(1000), sort_minimal_n(1000), sort_mwms_oversampling(10), sort_qs_num_samples_preset(100), sort_qsb_base_case_maximal_n(100), transform_minimal_n(1000), unique_copy_minimal_n(10000), workstealing_chunk_size(100), L1_cache_size(16 << 10), L2_cache_size(256 << 10), TLB_size(128), cache_line_size(64), qsb_steals(0), search_minimal_n(1000), find_scale_factor(0.01f) { } }; } #endif /* _GLIBCXX_PARALLEL_SETTINGS_H */ 8/parallel/checkers.h000064400000004374152526447520010473 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/checkers.h * @brief Routines for checking the correctness of algorithm results. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_CHECKERS_H #define _GLIBCXX_PARALLEL_CHECKERS_H 1 #include #include #include namespace __gnu_parallel { /** * @brief Check whether @c [__begin, @c __end) is sorted according * to @c __comp. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __comp Comparator. * @return @c true if sorted, @c false otherwise. */ template bool __is_sorted(_IIter __begin, _IIter __end, _Compare __comp) { if (__begin == __end) return true; _IIter __current(__begin), __recent(__begin); unsigned long long __position = 1; for (__current++; __current != __end; __current++) { if (__comp(*__current, *__recent)) { return false; } __recent = __current; __position++; } return true; } } #endif /* _GLIBCXX_PARALLEL_CHECKERS_H */ 8/parallel/losertree.h000064400000067660152526447520010717 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/losertree.h * @brief Many generic loser tree variants. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_LOSERTREE_H #define _GLIBCXX_PARALLEL_LOSERTREE_H 1 #include #include #include #include namespace __gnu_parallel { /** * @brief Guarded loser/tournament tree. * * The smallest element is at the top. * * Guarding is done explicitly through one flag _M_sup per element, * inf is not needed due to a better initialization routine. This * is a well-performing variant. * * @param _Tp the element type * @param _Compare the comparator to use, defaults to std::less<_Tp> */ template class _LoserTreeBase { protected: /** @brief Internal representation of a _LoserTree element. */ struct _Loser { /** @brief flag, true iff this is a "maximum" __sentinel. */ bool _M_sup; /** @brief __index of the __source __sequence. */ int _M_source; /** @brief _M_key of the element in the _LoserTree. */ _Tp _M_key; }; unsigned int _M_ik, _M_k, _M_offset; /** log_2{_M_k} */ unsigned int _M_log_k; /** @brief _LoserTree __elements. */ _Loser* _M_losers; /** @brief _Compare to use. */ _Compare _M_comp; /** * @brief State flag that determines whether the _LoserTree is empty. * * Only used for building the _LoserTree. */ bool _M_first_insert; public: /** * @brief The constructor. * * @param __k The number of sequences to merge. * @param __comp The comparator to use. */ _LoserTreeBase(unsigned int __k, _Compare __comp) : _M_comp(__comp) { _M_ik = __k; // Compute log_2{_M_k} for the _Loser Tree _M_log_k = __rd_log2(_M_ik - 1) + 1; // Next greater power of 2. _M_k = 1 << _M_log_k; _M_offset = _M_k; // Avoid default-constructing _M_losers[]._M_key _M_losers = static_cast<_Loser*>(::operator new(2 * _M_k * sizeof(_Loser))); for (unsigned int __i = _M_ik - 1; __i < _M_k; ++__i) _M_losers[__i + _M_k]._M_sup = true; _M_first_insert = true; } /** * @brief The destructor. */ ~_LoserTreeBase() { for (unsigned int __i = 0; __i < (2 * _M_k); ++__i) _M_losers[__i].~_Loser(); ::operator delete(_M_losers); } /** * @brief Initializes the sequence "_M_source" with the element "__key". * * @param __key the element to insert * @param __source __index of the __source __sequence * @param __sup flag that determines whether the value to insert is an * explicit __supremum. */ void __insert_start(const _Tp& __key, int __source, bool __sup) { unsigned int __pos = _M_k + __source; if (_M_first_insert) { // Construct all keys, so we can easily destruct them. for (unsigned int __i = 0; __i < (2 * _M_k); ++__i) ::new(&(_M_losers[__i]._M_key)) _Tp(__key); _M_first_insert = false; } else _M_losers[__pos]._M_key = __key; _M_losers[__pos]._M_sup = __sup; _M_losers[__pos]._M_source = __source; } /** * @return the index of the sequence with the smallest element. */ int __get_min_source() { return _M_losers[0]._M_source; } }; /** * @brief Stable _LoserTree variant. * * Provides the stable implementations of insert_start, __init_winner, * __init and __delete_min_insert. * * Unstable variant is done using partial specialisation below. */ template class _LoserTree : public _LoserTreeBase<_Tp, _Compare> { typedef _LoserTreeBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; using _Base::_M_first_insert; public: _LoserTree(unsigned int __k, _Compare __comp) : _Base::_LoserTreeBase(__k, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (_M_losers[__right]._M_sup || (!_M_losers[__left]._M_sup && !_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key))) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; } /** * @brief Delete the smallest element and insert a new element from * the previously smallest element's sequence. * * This implementation is stable. */ // Do not pass a const reference since __key will be used as // local variable. void __delete_min_insert(_Tp __key, bool __sup) { using std::swap; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted, ties are broken by _M_source. if ((__sup && (!_M_losers[__pos]._M_sup || _M_losers[__pos]._M_source < __source)) || (!__sup && !_M_losers[__pos]._M_sup && ((_M_comp(_M_losers[__pos]._M_key, __key)) || (!_M_comp(__key, _M_losers[__pos]._M_key) && _M_losers[__pos]._M_source < __source)))) { // The other one is smaller. std::swap(_M_losers[__pos]._M_sup, __sup); std::swap(_M_losers[__pos]._M_source, __source); swap(_M_losers[__pos]._M_key, __key); } } _M_losers[0]._M_sup = __sup; _M_losers[0]._M_source = __source; _M_losers[0]._M_key = __key; } }; /** * @brief Unstable _LoserTree variant. * * Stability (non-stable here) is selected with partial specialization. */ template class _LoserTree : public _LoserTreeBase<_Tp, _Compare> { typedef _LoserTreeBase<_Tp, _Compare> _Base; using _Base::_M_log_k; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; using _Base::_M_first_insert; public: _LoserTree(unsigned int __k, _Compare __comp) : _Base::_LoserTreeBase(__k, __comp) { } /** * Computes the winner of the competition at position "__root". * * Called recursively (starting at 0) to build the initial tree. * * @param __root __index of the "game" to start. */ unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (_M_losers[__right]._M_sup || (!_M_losers[__left]._M_sup && !_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key))) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; } /** * Delete the _M_key smallest element and insert the element __key * instead. * * @param __key the _M_key to insert * @param __sup true iff __key is an explicitly marked supremum */ // Do not pass a const reference since __key will be used as local // variable. void __delete_min_insert(_Tp __key, bool __sup) { using std::swap; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted. if (__sup || (!_M_losers[__pos]._M_sup && _M_comp(_M_losers[__pos]._M_key, __key))) { // The other one is smaller. std::swap(_M_losers[__pos]._M_sup, __sup); std::swap(_M_losers[__pos]._M_source, __source); swap(_M_losers[__pos]._M_key, __key); } } _M_losers[0]._M_sup = __sup; _M_losers[0]._M_source = __source; _M_losers[0]._M_key = __key; } }; /** * @brief Base class of _Loser Tree implementation using pointers. */ template class _LoserTreePointerBase { protected: /** @brief Internal representation of _LoserTree __elements. */ struct _Loser { bool _M_sup; int _M_source; const _Tp* _M_keyp; }; unsigned int _M_ik, _M_k, _M_offset; _Loser* _M_losers; _Compare _M_comp; public: _LoserTreePointerBase(unsigned int __k, _Compare __comp = std::less<_Tp>()) : _M_comp(__comp) { _M_ik = __k; // Next greater power of 2. _M_k = 1 << (__rd_log2(_M_ik - 1) + 1); _M_offset = _M_k; _M_losers = new _Loser[_M_k * 2]; for (unsigned int __i = _M_ik - 1; __i < _M_k; __i++) _M_losers[__i + _M_k]._M_sup = true; } ~_LoserTreePointerBase() { delete[] _M_losers; } int __get_min_source() { return _M_losers[0]._M_source; } void __insert_start(const _Tp& __key, int __source, bool __sup) { unsigned int __pos = _M_k + __source; _M_losers[__pos]._M_sup = __sup; _M_losers[__pos]._M_source = __source; _M_losers[__pos]._M_keyp = &__key; } }; /** * @brief Stable _LoserTree implementation. * * The unstable variant is implemented using partial instantiation below. */ template class _LoserTreePointer : public _LoserTreePointerBase<_Tp, _Compare> { typedef _LoserTreePointerBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreePointer(unsigned int __k, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreePointerBase(__k, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (_M_losers[__right]._M_sup || (!_M_losers[__left]._M_sup && !_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp))) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; } void __delete_min_insert(const _Tp& __key, bool __sup) { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif const _Tp* __keyp = &__key; int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted, ties are broken by __source. if ((__sup && (!_M_losers[__pos]._M_sup || _M_losers[__pos]._M_source < __source)) || (!__sup && !_M_losers[__pos]._M_sup && ((_M_comp(*_M_losers[__pos]._M_keyp, *__keyp)) || (!_M_comp(*__keyp, *_M_losers[__pos]._M_keyp) && _M_losers[__pos]._M_source < __source)))) { // The other one is smaller. std::swap(_M_losers[__pos]._M_sup, __sup); std::swap(_M_losers[__pos]._M_source, __source); std::swap(_M_losers[__pos]._M_keyp, __keyp); } } _M_losers[0]._M_sup = __sup; _M_losers[0]._M_source = __source; _M_losers[0]._M_keyp = __keyp; } }; /** * @brief Unstable _LoserTree implementation. * * The stable variant is above. */ template class _LoserTreePointer : public _LoserTreePointerBase<_Tp, _Compare> { typedef _LoserTreePointerBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreePointer(unsigned int __k, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreePointerBase(__k, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (_M_losers[__right]._M_sup || (!_M_losers[__left]._M_sup && !_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp))) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; } void __delete_min_insert(const _Tp& __key, bool __sup) { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif const _Tp* __keyp = &__key; int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted. if (__sup || (!_M_losers[__pos]._M_sup && _M_comp(*_M_losers[__pos]._M_keyp, *__keyp))) { // The other one is smaller. std::swap(_M_losers[__pos]._M_sup, __sup); std::swap(_M_losers[__pos]._M_source, __source); std::swap(_M_losers[__pos]._M_keyp, __keyp); } } _M_losers[0]._M_sup = __sup; _M_losers[0]._M_source = __source; _M_losers[0]._M_keyp = __keyp; } }; /** @brief Base class for unguarded _LoserTree implementation. * * The whole element is copied into the tree structure. * * No guarding is done, therefore not a single input sequence must * run empty. Unused __sequence heads are marked with a sentinel which * is > all elements that are to be merged. * * This is a very fast variant. */ template class _LoserTreeUnguardedBase { protected: struct _Loser { int _M_source; _Tp _M_key; }; unsigned int _M_ik, _M_k, _M_offset; _Loser* _M_losers; _Compare _M_comp; public: _LoserTreeUnguardedBase(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _M_comp(__comp) { _M_ik = __k; // Next greater power of 2. _M_k = 1 << (__rd_log2(_M_ik - 1) + 1); _M_offset = _M_k; // Avoid default-constructing _M_losers[]._M_key _M_losers = static_cast<_Loser*>(::operator new(2 * _M_k * sizeof(_Loser))); for (unsigned int __i = 0; __i < _M_k; ++__i) { ::new(&(_M_losers[__i]._M_key)) _Tp(__sentinel); _M_losers[__i]._M_source = -1; } for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i) { ::new(&(_M_losers[__i]._M_key)) _Tp(__sentinel); _M_losers[__i]._M_source = -1; } } ~_LoserTreeUnguardedBase() { for (unsigned int __i = 0; __i < (2 * _M_k); ++__i) _M_losers[__i].~_Loser(); ::operator delete(_M_losers); } int __get_min_source() { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif return _M_losers[0]._M_source; } void __insert_start(const _Tp& __key, int __source, bool) { unsigned int __pos = _M_k + __source; ::new(&(_M_losers[__pos]._M_key)) _Tp(__key); _M_losers[__pos]._M_source = __source; } }; /** * @brief Stable implementation of unguarded _LoserTree. * * Unstable variant is selected below with partial specialization. */ template class _LoserTreeUnguarded : public _LoserTreeUnguardedBase<_Tp, _Compare> { typedef _LoserTreeUnguardedBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreeUnguarded(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreeUnguardedBase(__k, __sentinel, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (!_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key)) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top at the beginning // (0 sequences!) _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif } // Do not pass a const reference since __key will be used as // local variable. void __delete_min_insert(_Tp __key, bool) { using std::swap; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted, ties are broken by _M_source. if (_M_comp(_M_losers[__pos]._M_key, __key) || (!_M_comp(__key, _M_losers[__pos]._M_key) && _M_losers[__pos]._M_source < __source)) { // The other one is smaller. std::swap(_M_losers[__pos]._M_source, __source); swap(_M_losers[__pos]._M_key, __key); } } _M_losers[0]._M_source = __source; _M_losers[0]._M_key = __key; } }; /** * @brief Non-Stable implementation of unguarded _LoserTree. * * Stable implementation is above. */ template class _LoserTreeUnguarded : public _LoserTreeUnguardedBase<_Tp, _Compare> { typedef _LoserTreeUnguardedBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreeUnguarded(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreeUnguardedBase(__k, __sentinel, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); #if _GLIBCXX_PARALLEL_ASSERTIONS // If __left one is sentinel then __right one must be, too. if (_M_losers[__left]._M_source == -1) _GLIBCXX_PARALLEL_ASSERT(_M_losers[__right]._M_source == -1); #endif if (!_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key)) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top at the beginning // (0 sequences!) _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif } // Do not pass a const reference since __key will be used as // local variable. void __delete_min_insert(_Tp __key, bool) { using std::swap; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted. if (_M_comp(_M_losers[__pos]._M_key, __key)) { // The other one is smaller. std::swap(_M_losers[__pos]._M_source, __source); swap(_M_losers[__pos]._M_key, __key); } } _M_losers[0]._M_source = __source; _M_losers[0]._M_key = __key; } }; /** @brief Unguarded loser tree, keeping only pointers to the * elements in the tree structure. * * No guarding is done, therefore not a single input sequence must * run empty. This is a very fast variant. */ template class _LoserTreePointerUnguardedBase { protected: struct _Loser { int _M_source; const _Tp* _M_keyp; }; unsigned int _M_ik, _M_k, _M_offset; _Loser* _M_losers; _Compare _M_comp; public: _LoserTreePointerUnguardedBase(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _M_comp(__comp) { _M_ik = __k; // Next greater power of 2. _M_k = 1 << (__rd_log2(_M_ik - 1) + 1); _M_offset = _M_k; // Avoid default-constructing _M_losers[]._M_key _M_losers = new _Loser[2 * _M_k]; for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i) { _M_losers[__i]._M_keyp = &__sentinel; _M_losers[__i]._M_source = -1; } } ~_LoserTreePointerUnguardedBase() { delete[] _M_losers; } int __get_min_source() { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif return _M_losers[0]._M_source; } void __insert_start(const _Tp& __key, int __source, bool) { unsigned int __pos = _M_k + __source; _M_losers[__pos]._M_keyp = &__key; _M_losers[__pos]._M_source = __source; } }; /** * @brief Stable unguarded _LoserTree variant storing pointers. * * Unstable variant is implemented below using partial specialization. */ template class _LoserTreePointerUnguarded : public _LoserTreePointerUnguardedBase<_Tp, _Compare> { typedef _LoserTreePointerUnguardedBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreePointerUnguarded(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreePointerUnguardedBase(__k, __sentinel, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (!_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp)) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top at the beginning // (0 sequences!) _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif } void __delete_min_insert(const _Tp& __key, bool __sup) { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif const _Tp* __keyp = &__key; int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted, ties are broken by _M_source. if (_M_comp(*_M_losers[__pos]._M_keyp, *__keyp) || (!_M_comp(*__keyp, *_M_losers[__pos]._M_keyp) && _M_losers[__pos]._M_source < __source)) { // The other one is smaller. std::swap(_M_losers[__pos]._M_source, __source); std::swap(_M_losers[__pos]._M_keyp, __keyp); } } _M_losers[0]._M_source = __source; _M_losers[0]._M_keyp = __keyp; } }; /** * @brief Unstable unguarded _LoserTree variant storing pointers. * * Stable variant is above. */ template class _LoserTreePointerUnguarded : public _LoserTreePointerUnguardedBase<_Tp, _Compare> { typedef _LoserTreePointerUnguardedBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreePointerUnguarded(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreePointerUnguardedBase(__k, __sentinel, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); #if _GLIBCXX_PARALLEL_ASSERTIONS // If __left one is sentinel then __right one must be, too. if (_M_losers[__left]._M_source == -1) _GLIBCXX_PARALLEL_ASSERT(_M_losers[__right]._M_source == -1); #endif if (!_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp)) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top at the beginning // (0 sequences!) _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif } void __delete_min_insert(const _Tp& __key, bool __sup) { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif const _Tp* __keyp = &__key; int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted. if (_M_comp(*(_M_losers[__pos]._M_keyp), *__keyp)) { // The other one is smaller. std::swap(_M_losers[__pos]._M_source, __source); std::swap(_M_losers[__pos]._M_keyp, __keyp); } } _M_losers[0]._M_source = __source; _M_losers[0]._M_keyp = __keyp; } }; } // namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_LOSERTREE_H */ 8/parallel/parallel.h000064400000003050152526447520010466 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/parallel.h * @brief End-user include file. Provides advanced settings and * tuning options. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze and Johannes Singler. #ifndef _GLIBCXX_PARALLEL_PARALLEL_H #define _GLIBCXX_PARALLEL_PARALLEL_H 1 #include #include #include #include #include #endif /* _GLIBCXX_PARALLEL_PARALLEL_H */ 8/parallel/algobase.h000064400000041403152526447520010453 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/algobase.h * @brief Parallel STL function calls corresponding to the * stl_algobase.h header. The functions defined here mainly do case * switches and call the actual parallelized versions in other files. * Inlining policy: Functions that basically only contain one * function call, are declared inline. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_ALGOBASE_H #define _GLIBCXX_PARALLEL_ALGOBASE_H 1 #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { // NB: equal and lexicographical_compare require mismatch. // Sequential fallback template inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2); } // Sequential fallback template inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); } // Sequential fallback for input iterator case template inline pair<_IIter1, _IIter2> __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); } // Parallel mismatch for random access iterators template pair<_RAIter1, _RAIter2> __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) { _RAIter1 __res = __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred, __gnu_parallel:: __mismatch_selector()).first; return make_pair(__res , __begin2 + (__res - __begin1)); } else return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); } // Public interface template inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2) { typedef __gnu_parallel::_EqualTo< typename std::iterator_traits<_IIter1>::value_type, typename std::iterator_traits<_IIter2>::value_type> _EqualTo; return __mismatch_switch(__begin1, __end1, __begin2, _EqualTo(), std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } // Public interface template inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred) { return __mismatch_switch(__begin1, __end1, __begin2, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } #if __cplusplus > 201103L // Sequential fallback. template inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2); } // Sequential fallback. template inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2, __binary_pred); } // Sequential fallback for input iterator case template inline pair<_IIter1, _IIter2> __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __end2, __pred); } // Parallel mismatch for random access iterators template pair<_RAIter1, _RAIter2> __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) { if ((__end2 - __begin2) < (__end1 - __begin1)) __end1 = __begin1 + (__end2 - __begin2); _RAIter1 __res = __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred, __gnu_parallel:: __mismatch_selector()).first; return make_pair(__res , __begin2 + (__res - __begin1)); } else return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __end2, __pred); } template inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2) { typedef __gnu_parallel::_EqualTo< typename std::iterator_traits<_IIter1>::value_type, typename std::iterator_traits<_IIter2>::value_type> _EqualTo; return __mismatch_switch(__begin1, __end1, __begin2, __end2, _EqualTo(), std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } template inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __begin1, _InputIterator1 __end1, _InputIterator2 __begin2, _InputIterator2 __end2, _BinaryPredicate __binary_pred) { return __mismatch_switch(__begin1, __end1, __begin2, __end2, __binary_pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } #endif // Sequential fallback template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2); } // Sequential fallback template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __pred); } // Public interface template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2) { return __gnu_parallel::mismatch(__begin1, __end1, __begin2).first == __end1; } // Public interface template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred) { return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __pred).first == __end1; } #if __cplusplus > 201103L // Sequential fallback template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2); } // Sequential fallback template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2, __binary_pred); } // Sequential fallback for input iterator case template inline bool __equal_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2, __pred); } // Parallel equal for random access iterators template inline bool __equal_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) { if (std::distance(__begin1, __end1) != std::distance(__begin2, __end2)) return false; return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __end2, __pred).first == __end1; } else return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2, __pred); } template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2) { typedef __gnu_parallel::_EqualTo< typename std::iterator_traits<_IIter1>::value_type, typename std::iterator_traits<_IIter2>::value_type> _EqualTo; return __equal_switch(__begin1, __end1, __begin2, __end2, _EqualTo(), std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } template inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _BinaryPredicate __binary_pred) { return __equal_switch(__begin1, __end1, __begin2, __end2, __binary_pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } #endif // Sequential fallback template inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::lexicographical_compare(__begin1, __end1, __begin2, __end2); } // Sequential fallback template inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::lexicographical_compare( __begin1, __end1, __begin2, __end2, __pred); } // Sequential fallback for input iterator case template inline bool __lexicographical_compare_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::lexicographical_compare( __begin1, __end1, __begin2, __end2, __pred); } // Parallel lexicographical_compare for random access iterators // Limitation: Both valuetypes must be the same template bool __lexicographical_compare_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) { typedef iterator_traits<_RAIter1> _TraitsType1; typedef typename _TraitsType1::value_type _ValueType1; typedef iterator_traits<_RAIter2> _TraitsType2; typedef typename _TraitsType2::value_type _ValueType2; typedef __gnu_parallel:: _EqualFromLess<_ValueType1, _ValueType2, _Predicate> _EqualFromLessCompare; // Longer sequence in first place. if ((__end1 - __begin1) < (__end2 - __begin2)) { typedef pair<_RAIter1, _RAIter2> _SpotType; _SpotType __mm = __mismatch_switch(__begin1, __end1, __begin2, _EqualFromLessCompare(__pred), random_access_iterator_tag(), random_access_iterator_tag()); return (__mm.first == __end1) || bool(__pred(*__mm.first, *__mm.second)); } else { typedef pair<_RAIter2, _RAIter1> _SpotType; _SpotType __mm = __mismatch_switch(__begin2, __end2, __begin1, _EqualFromLessCompare(__pred), random_access_iterator_tag(), random_access_iterator_tag()); return (__mm.first != __end2) && bool(__pred(*__mm.second, *__mm.first)); } } else return _GLIBCXX_STD_A::lexicographical_compare( __begin1, __end1, __begin2, __end2, __pred); } // Public interface template inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::value_type _ValueType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::value_type _ValueType2; typedef typename _TraitsType2::iterator_category _IteratorCategory2; typedef __gnu_parallel::_Less<_ValueType1, _ValueType2> _LessType; return __lexicographical_compare_switch( __begin1, __end1, __begin2, __end2, _LessType(), _IteratorCategory1(), _IteratorCategory2()); } // Public interface template inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::iterator_category _IteratorCategory2; return __lexicographical_compare_switch( __begin1, __end1, __begin2, __end2, __pred, _IteratorCategory1(), _IteratorCategory2()); } } // end namespace } // end namespace #endif /* _GLIBCXX_PARALLEL_ALGOBASE_H */ 8/parallel/random_shuffle.h000064400000044363152526447520011702 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/random_shuffle.h * @brief Parallel implementation of std::random_shuffle(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_RANDOM_SHUFFLE_H #define _GLIBCXX_PARALLEL_RANDOM_SHUFFLE_H 1 #include #include #include #include namespace __gnu_parallel { /** @brief Type to hold the index of a bin. * * Since many variables of this type are allocated, it should be * chosen as small as possible. */ typedef unsigned short _BinIndex; /** @brief Data known to every thread participating in __gnu_parallel::__parallel_random_shuffle(). */ template struct _DRandomShufflingGlobalData { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; /** @brief Begin iterator of the __source. */ _RAIter& _M_source; /** @brief Temporary arrays for each thread. */ _ValueType** _M_temporaries; /** @brief Two-dimensional array to hold the thread-bin distribution. * * Dimensions (_M_num_threads + 1) __x (_M_num_bins + 1). */ _DifferenceType** _M_dist; /** @brief Start indexes of the threads' __chunks. */ _DifferenceType* _M_starts; /** @brief Number of the thread that will further process the corresponding bin. */ _ThreadIndex* _M_bin_proc; /** @brief Number of bins to distribute to. */ int _M_num_bins; /** @brief Number of bits needed to address the bins. */ int _M_num_bits; /** @brief Constructor. */ _DRandomShufflingGlobalData(_RAIter& __source) : _M_source(__source) { } }; /** @brief Local data for a thread participating in __gnu_parallel::__parallel_random_shuffle(). */ template struct _DRSSorterPU { /** @brief Number of threads participating in total. */ int _M_num_threads; /** @brief Begin index for bins taken care of by this thread. */ _BinIndex _M_bins_begin; /** @brief End index for bins taken care of by this thread. */ _BinIndex __bins_end; /** @brief Random _M_seed for this thread. */ uint32_t _M_seed; /** @brief Pointer to global data. */ _DRandomShufflingGlobalData<_RAIter>* _M_sd; }; /** @brief Generate a random number in @c [0,2^__logp). * @param __logp Logarithm (basis 2) of the upper range __bound. * @param __rng Random number generator to use. */ template inline int __random_number_pow2(int __logp, _RandomNumberGenerator& __rng) { return __rng.__genrand_bits(__logp); } /** @brief Random shuffle code executed by each thread. * @param __pus Array of thread-local data records. */ template void __parallel_random_shuffle_drs_pu(_DRSSorterPU<_RAIter, _RandomNumberGenerator>* __pus) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _ThreadIndex __iam = omp_get_thread_num(); _DRSSorterPU<_RAIter, _RandomNumberGenerator>* __d = &__pus[__iam]; _DRandomShufflingGlobalData<_RAIter>* __sd = __d->_M_sd; // Indexing: _M_dist[bin][processor] _DifferenceType __length = (__sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam]); _BinIndex* __oracles = new _BinIndex[__length]; _DifferenceType* __dist = new _DifferenceType[__sd->_M_num_bins + 1]; _BinIndex* __bin_proc = new _BinIndex[__sd->_M_num_bins]; _ValueType** __temporaries = new _ValueType*[__d->_M_num_threads]; // Compute oracles and count appearances. for (_BinIndex __b = 0; __b < __sd->_M_num_bins + 1; ++__b) __dist[__b] = 0; int __num_bits = __sd->_M_num_bits; _RandomNumber __rng(__d->_M_seed); // First main loop. for (_DifferenceType __i = 0; __i < __length; ++__i) { _BinIndex __oracle = __random_number_pow2(__num_bits, __rng); __oracles[__i] = __oracle; // To allow prefix (partial) sum. ++(__dist[__oracle + 1]); } for (_BinIndex __b = 0; __b < __sd->_M_num_bins + 1; ++__b) __sd->_M_dist[__b][__iam + 1] = __dist[__b]; # pragma omp barrier # pragma omp single { // Sum up bins, __sd->_M_dist[__s + 1][__d->_M_num_threads] now // contains the total number of items in bin __s for (_BinIndex __s = 0; __s < __sd->_M_num_bins; ++__s) __gnu_sequential::partial_sum(__sd->_M_dist[__s + 1], __sd->_M_dist[__s + 1] + __d->_M_num_threads + 1, __sd->_M_dist[__s + 1]); } # pragma omp barrier _SequenceIndex __offset = 0, __global_offset = 0; for (_BinIndex __s = 0; __s < __d->_M_bins_begin; ++__s) __global_offset += __sd->_M_dist[__s + 1][__d->_M_num_threads]; # pragma omp barrier for (_BinIndex __s = __d->_M_bins_begin; __s < __d->__bins_end; ++__s) { for (int __t = 0; __t < __d->_M_num_threads + 1; ++__t) __sd->_M_dist[__s + 1][__t] += __offset; __offset = __sd->_M_dist[__s + 1][__d->_M_num_threads]; } __sd->_M_temporaries[__iam] = static_cast<_ValueType*> (::operator new(sizeof(_ValueType) * __offset)); # pragma omp barrier // Draw local copies to avoid false sharing. for (_BinIndex __b = 0; __b < __sd->_M_num_bins + 1; ++__b) __dist[__b] = __sd->_M_dist[__b][__iam]; for (_BinIndex __b = 0; __b < __sd->_M_num_bins; ++__b) __bin_proc[__b] = __sd->_M_bin_proc[__b]; for (_ThreadIndex __t = 0; __t < __d->_M_num_threads; ++__t) __temporaries[__t] = __sd->_M_temporaries[__t]; _RAIter __source = __sd->_M_source; _DifferenceType __start = __sd->_M_starts[__iam]; // Distribute according to oracles, second main loop. for (_DifferenceType __i = 0; __i < __length; ++__i) { _BinIndex __target_bin = __oracles[__i]; _ThreadIndex __target_p = __bin_proc[__target_bin]; // Last column [__d->_M_num_threads] stays unchanged. ::new(&(__temporaries[__target_p][__dist[__target_bin + 1]++])) _ValueType(*(__source + __i + __start)); } delete[] __oracles; delete[] __dist; delete[] __bin_proc; delete[] __temporaries; # pragma omp barrier // Shuffle bins internally. for (_BinIndex __b = __d->_M_bins_begin; __b < __d->__bins_end; ++__b) { _ValueType* __begin = (__sd->_M_temporaries[__iam] + (__b == __d->_M_bins_begin ? 0 : __sd->_M_dist[__b][__d->_M_num_threads])), *__end = (__sd->_M_temporaries[__iam] + __sd->_M_dist[__b + 1][__d->_M_num_threads]); __sequential_random_shuffle(__begin, __end, __rng); std::copy(__begin, __end, __sd->_M_source + __global_offset + (__b == __d->_M_bins_begin ? 0 : __sd->_M_dist[__b][__d->_M_num_threads])); } for (_SequenceIndex __i = 0; __i < __offset; ++__i) __sd->_M_temporaries[__iam][__i].~_ValueType(); ::operator delete(__sd->_M_temporaries[__iam]); } /** @brief Round up to the next greater power of 2. * @param __x _Integer to round up */ template _Tp __round_up_to_pow2(_Tp __x) { if (__x <= 1) return 1; else return (_Tp)1 << (__rd_log2(__x - 1) + 1); } /** @brief Main parallel random shuffle step. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __n Length of sequence. * @param __num_threads Number of threads to use. * @param __rng Random number generator to use. */ template void __parallel_random_shuffle_drs(_RAIter __begin, _RAIter __end, typename std::iterator_traits <_RAIter>::difference_type __n, _ThreadIndex __num_threads, _RandomNumberGenerator& __rng) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _GLIBCXX_CALL(__n) const _Settings& __s = _Settings::get(); if (__num_threads > __n) __num_threads = static_cast<_ThreadIndex>(__n); _BinIndex __num_bins, __num_bins_cache; #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 // Try the L1 cache first. // Must fit into L1. __num_bins_cache = std::max<_DifferenceType>(1, __n / (__s.L1_cache_size_lb / sizeof(_ValueType))); __num_bins_cache = __round_up_to_pow2(__num_bins_cache); // No more buckets than TLB entries, power of 2 // Power of 2 and at least one element per bin, at most the TLB size. __num_bins = std::min<_DifferenceType>(__n, __num_bins_cache); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB // 2 TLB entries needed per bin. __num_bins = std::min<_DifferenceType>(__s.TLB_size / 2, __num_bins); #endif __num_bins = __round_up_to_pow2(__num_bins); if (__num_bins < __num_bins_cache) { #endif // Now try the L2 cache // Must fit into L2 __num_bins_cache = static_cast<_BinIndex> (std::max<_DifferenceType>(1, __n / (__s.L2_cache_size / sizeof(_ValueType)))); __num_bins_cache = __round_up_to_pow2(__num_bins_cache); // No more buckets than TLB entries, power of 2. __num_bins = static_cast<_BinIndex> (std::min(__n, static_cast<_DifferenceType>(__num_bins_cache))); // Power of 2 and at least one element per bin, at most the TLB size. #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB // 2 TLB entries needed per bin. __num_bins = std::min(static_cast<_DifferenceType>(__s.TLB_size / 2), __num_bins); #endif __num_bins = __round_up_to_pow2(__num_bins); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 } #endif __num_bins = __round_up_to_pow2( std::max<_BinIndex>(__num_threads, __num_bins)); if (__num_threads <= 1) { _RandomNumber __derived_rng( __rng(std::numeric_limits::max())); __sequential_random_shuffle(__begin, __end, __derived_rng); return; } _DRandomShufflingGlobalData<_RAIter> __sd(__begin); _DRSSorterPU<_RAIter, _RandomNumber >* __pus; _DifferenceType* __starts; # pragma omp parallel num_threads(__num_threads) { _ThreadIndex __num_threads = omp_get_num_threads(); # pragma omp single { __pus = new _DRSSorterPU<_RAIter, _RandomNumber>[__num_threads]; __sd._M_temporaries = new _ValueType*[__num_threads]; __sd._M_dist = new _DifferenceType*[__num_bins + 1]; __sd._M_bin_proc = new _ThreadIndex[__num_bins]; for (_BinIndex __b = 0; __b < __num_bins + 1; ++__b) __sd._M_dist[__b] = new _DifferenceType[__num_threads + 1]; for (_BinIndex __b = 0; __b < (__num_bins + 1); ++__b) { __sd._M_dist[0][0] = 0; __sd._M_dist[__b][0] = 0; } __starts = __sd._M_starts = new _DifferenceType[__num_threads + 1]; int __bin_cursor = 0; __sd._M_num_bins = __num_bins; __sd._M_num_bits = __rd_log2(__num_bins); _DifferenceType __chunk_length = __n / __num_threads, __split = __n % __num_threads, __start = 0; _DifferenceType __bin_chunk_length = __num_bins / __num_threads, __bin_split = __num_bins % __num_threads; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) { __starts[__i] = __start; __start += (__i < __split ? (__chunk_length + 1) : __chunk_length); int __j = __pus[__i]._M_bins_begin = __bin_cursor; // Range of bins for this processor. __bin_cursor += (__i < __bin_split ? (__bin_chunk_length + 1) : __bin_chunk_length); __pus[__i].__bins_end = __bin_cursor; for (; __j < __bin_cursor; ++__j) __sd._M_bin_proc[__j] = __i; __pus[__i]._M_num_threads = __num_threads; __pus[__i]._M_seed = __rng(std::numeric_limits::max()); __pus[__i]._M_sd = &__sd; } __starts[__num_threads] = __start; } //single // Now shuffle in parallel. __parallel_random_shuffle_drs_pu(__pus); } // parallel delete[] __starts; delete[] __sd._M_bin_proc; for (int __s = 0; __s < (__num_bins + 1); ++__s) delete[] __sd._M_dist[__s]; delete[] __sd._M_dist; delete[] __sd._M_temporaries; delete[] __pus; } /** @brief Sequential cache-efficient random shuffle. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __rng Random number generator to use. */ template void __sequential_random_shuffle(_RAIter __begin, _RAIter __end, _RandomNumberGenerator& __rng) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; const _Settings& __s = _Settings::get(); _BinIndex __num_bins, __num_bins_cache; #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 // Try the L1 cache first, must fit into L1. __num_bins_cache = std::max<_DifferenceType> (1, __n / (__s.L1_cache_size_lb / sizeof(_ValueType))); __num_bins_cache = __round_up_to_pow2(__num_bins_cache); // No more buckets than TLB entries, power of 2 // Power of 2 and at least one element per bin, at most the TLB size __num_bins = std::min(__n, (_DifferenceType)__num_bins_cache); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB // 2 TLB entries needed per bin __num_bins = std::min((_DifferenceType)__s.TLB_size / 2, __num_bins); #endif __num_bins = __round_up_to_pow2(__num_bins); if (__num_bins < __num_bins_cache) { #endif // Now try the L2 cache, must fit into L2. __num_bins_cache = static_cast<_BinIndex> (std::max<_DifferenceType>(1, __n / (__s.L2_cache_size / sizeof(_ValueType)))); __num_bins_cache = __round_up_to_pow2(__num_bins_cache); // No more buckets than TLB entries, power of 2 // Power of 2 and at least one element per bin, at most the TLB size. __num_bins = static_cast<_BinIndex> (std::min(__n, static_cast<_DifferenceType>(__num_bins_cache))); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB // 2 TLB entries needed per bin __num_bins = std::min<_DifferenceType>(__s.TLB_size / 2, __num_bins); #endif __num_bins = __round_up_to_pow2(__num_bins); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 } #endif int __num_bits = __rd_log2(__num_bins); if (__num_bins > 1) { _ValueType* __target = static_cast<_ValueType*>(::operator new(sizeof(_ValueType) * __n)); _BinIndex* __oracles = new _BinIndex[__n]; _DifferenceType* __dist0 = new _DifferenceType[__num_bins + 1], * __dist1 = new _DifferenceType[__num_bins + 1]; for (int __b = 0; __b < __num_bins + 1; ++__b) __dist0[__b] = 0; _RandomNumber __bitrng(__rng(0xFFFFFFFF)); for (_DifferenceType __i = 0; __i < __n; ++__i) { _BinIndex __oracle = __random_number_pow2(__num_bits, __bitrng); __oracles[__i] = __oracle; // To allow prefix (partial) sum. ++(__dist0[__oracle + 1]); } // Sum up bins. __gnu_sequential::partial_sum(__dist0, __dist0 + __num_bins + 1, __dist0); for (int __b = 0; __b < __num_bins + 1; ++__b) __dist1[__b] = __dist0[__b]; // Distribute according to oracles. for (_DifferenceType __i = 0; __i < __n; ++__i) ::new(&(__target[(__dist0[__oracles[__i]])++])) _ValueType(*(__begin + __i)); for (int __b = 0; __b < __num_bins; ++__b) __sequential_random_shuffle(__target + __dist1[__b], __target + __dist1[__b + 1], __rng); // Copy elements back. std::copy(__target, __target + __n, __begin); delete[] __dist0; delete[] __dist1; delete[] __oracles; for (_DifferenceType __i = 0; __i < __n; ++__i) __target[__i].~_ValueType(); ::operator delete(__target); } else __gnu_sequential::random_shuffle(__begin, __end, __rng); } /** @brief Parallel random public call. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __rng Random number generator to use. */ template inline void __parallel_random_shuffle(_RAIter __begin, _RAIter __end, _RandomNumberGenerator __rng = _RandomNumber()) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; __parallel_random_shuffle_drs(__begin, __end, __n, __get_max_threads(), __rng); } } #endif /* _GLIBCXX_PARALLEL_RANDOM_SHUFFLE_H */ 8/parallel/search.h000064400000012417152526447520010146 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/search.h * @brief Parallel implementation base for std::search() and * std::search_n(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_SEARCH_H #define _GLIBCXX_PARALLEL_SEARCH_H 1 #include #include #include namespace __gnu_parallel { /** * @brief Precalculate __advances for Knuth-Morris-Pratt algorithm. * @param __elements Begin iterator of sequence to search for. * @param __length Length of sequence to search for. * @param __off Returned __offsets. */ template void __calc_borders(_RAIter __elements, _DifferenceTp __length, _DifferenceTp* __off) { typedef _DifferenceTp _DifferenceType; __off[0] = -1; if (__length > 1) __off[1] = 0; _DifferenceType __k = 0; for (_DifferenceType __j = 2; __j <= __length; __j++) { while ((__k >= 0) && !(__elements[__k] == __elements[__j-1])) __k = __off[__k]; __off[__j] = ++__k; } } // Generic parallel find algorithm (requires random access iterator). /** @brief Parallel std::search. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __pred Find predicate. * @return Place of finding in first sequences. */ template __RAIter1 __search_template(__RAIter1 __begin1, __RAIter1 __end1, __RAIter2 __begin2, __RAIter2 __end2, _Pred __pred) { typedef std::iterator_traits<__RAIter1> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2)); _DifferenceType __pattern_length = __end2 - __begin2; // Pattern too short. if(__pattern_length <= 0) return __end1; // Last point to start search. _DifferenceType __input_length = (__end1 - __begin1) - __pattern_length; // Where is first occurrence of pattern? defaults to end. _DifferenceType __result = (__end1 - __begin1); _DifferenceType *__splitters; // Pattern too long. if (__input_length < 0) return __end1; omp_lock_t __result_lock; omp_init_lock(&__result_lock); _ThreadIndex __num_threads = std::max<_DifferenceType> (1, std::min<_DifferenceType>(__input_length, __get_max_threads())); _DifferenceType __advances[__pattern_length]; __calc_borders(__begin2, __pattern_length, __advances); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __splitters = new _DifferenceType[__num_threads + 1]; __equally_split(__input_length, __num_threads, __splitters); } _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __start = __splitters[__iam], __stop = __splitters[__iam + 1]; _DifferenceType __pos_in_pattern = 0; bool __found_pattern = false; while (__start <= __stop && !__found_pattern) { // Get new value of result. #pragma omp flush(__result) // No chance for this thread to find first occurrence. if (__result < __start) break; while (__pred(__begin1[__start + __pos_in_pattern], __begin2[__pos_in_pattern])) { ++__pos_in_pattern; if (__pos_in_pattern == __pattern_length) { // Found new candidate for result. omp_set_lock(&__result_lock); __result = std::min(__result, __start); omp_unset_lock(&__result_lock); __found_pattern = true; break; } } // Make safe jump. __start += (__pos_in_pattern - __advances[__pos_in_pattern]); __pos_in_pattern = (__advances[__pos_in_pattern] < 0 ? 0 : __advances[__pos_in_pattern]); } } //parallel omp_destroy_lock(&__result_lock); delete[] __splitters; // Return iterator on found element. return (__begin1 + __result); } } // end namespace #endif /* _GLIBCXX_PARALLEL_SEARCH_H */ 8/parallel/for_each.h000064400000007553152526447520010454 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/for_each.h * @brief Main interface for embarrassingly parallel functions. * * The explicit implementation are in other header files, like * workstealing.h, par_loop.h, omp_loop.h, and omp_loop_static.h. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_FOR_EACH_H #define _GLIBCXX_PARALLEL_FOR_EACH_H 1 #include #include #include #include namespace __gnu_parallel { /** @brief Chose the desired algorithm by evaluating @c __parallelism_tag. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __user_op A user-specified functor (comparator, predicate, * associative operator,...) * @param __functionality functor to @a process an element with * __user_op (depends on desired functionality, e. g. accumulate, * for_each,... * @param __reduction Reduction functor. * @param __reduction_start Initial value for reduction. * @param __output Output iterator. * @param __bound Maximum number of elements processed. * @param __parallelism_tag Parallelization method */ template _UserOp __for_each_template_random_access(_IIter __begin, _IIter __end, _UserOp __user_op, _Functionality& __functionality, _Red __reduction, _Result __reduction_start, _Result& __output, typename std::iterator_traits<_IIter>:: difference_type __bound, _Parallelism __parallelism_tag) { if (__parallelism_tag == parallel_unbalanced) return __for_each_template_random_access_ed (__begin, __end, __user_op, __functionality, __reduction, __reduction_start, __output, __bound); else if (__parallelism_tag == parallel_omp_loop) return __for_each_template_random_access_omp_loop (__begin, __end, __user_op, __functionality, __reduction, __reduction_start, __output, __bound); else if (__parallelism_tag == parallel_omp_loop_static) return __for_each_template_random_access_omp_loop (__begin, __end, __user_op, __functionality, __reduction, __reduction_start, __output, __bound); else //e. g. parallel_balanced return __for_each_template_random_access_workstealing (__begin, __end, __user_op, __functionality, __reduction, __reduction_start, __output, __bound); } } #endif /* _GLIBCXX_PARALLEL_FOR_EACH_H */ 8/parallel/quicksort.h000064400000013756152526447520010734 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/quicksort.h * @brief Implementation of a unbalanced parallel quicksort (in-place). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_QUICKSORT_H #define _GLIBCXX_PARALLEL_QUICKSORT_H 1 #include #include namespace __gnu_parallel { /** @brief Unbalanced quicksort divide step. * @param __begin Begin iterator of subsequence. * @param __end End iterator of subsequence. * @param __comp Comparator. * @param __pivot_rank Desired __rank of the pivot. * @param __num_samples Choose pivot from that many samples. * @param __num_threads Number of threads that are allowed to work on * this part. */ template typename std::iterator_traits<_RAIter>::difference_type __parallel_sort_qs_divide(_RAIter __begin, _RAIter __end, _Compare __comp, typename std::iterator_traits <_RAIter>::difference_type __pivot_rank, typename std::iterator_traits <_RAIter>::difference_type __num_samples, _ThreadIndex __num_threads) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; __num_samples = std::min(__num_samples, __n); // Allocate uninitialized, to avoid default constructor. _ValueType* __samples = static_cast<_ValueType*> (::operator new(__num_samples * sizeof(_ValueType))); for (_DifferenceType __s = 0; __s < __num_samples; ++__s) { const unsigned long long __index = static_cast (__s) * __n / __num_samples; ::new(&(__samples[__s])) _ValueType(__begin[__index]); } __gnu_sequential::sort(__samples, __samples + __num_samples, __comp); _ValueType& __pivot = __samples[__pivot_rank * __num_samples / __n]; __gnu_parallel::__binder2nd<_Compare, _ValueType, _ValueType, bool> __pred(__comp, __pivot); _DifferenceType __split = __parallel_partition(__begin, __end, __pred, __num_threads); for (_DifferenceType __s = 0; __s < __num_samples; ++__s) __samples[__s].~_ValueType(); ::operator delete(__samples); return __split; } /** @brief Unbalanced quicksort conquer step. * @param __begin Begin iterator of subsequence. * @param __end End iterator of subsequence. * @param __comp Comparator. * @param __num_threads Number of threads that are allowed to work on * this part. */ template void __parallel_sort_qs_conquer(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; if (__num_threads <= 1) { __gnu_sequential::sort(__begin, __end, __comp); return; } _DifferenceType __n = __end - __begin, __pivot_rank; if (__n <= 1) return; _ThreadIndex __num_threads_left; if ((__num_threads % 2) == 1) __num_threads_left = __num_threads / 2 + 1; else __num_threads_left = __num_threads / 2; __pivot_rank = __n * __num_threads_left / __num_threads; _DifferenceType __split = __parallel_sort_qs_divide (__begin, __end, __comp, __pivot_rank, _Settings::get().sort_qs_num_samples_preset, __num_threads); #pragma omp parallel sections num_threads(2) { #pragma omp section __parallel_sort_qs_conquer(__begin, __begin + __split, __comp, __num_threads_left); #pragma omp section __parallel_sort_qs_conquer(__begin + __split, __end, __comp, __num_threads - __num_threads_left); } } /** @brief Unbalanced quicksort main call. * @param __begin Begin iterator of input sequence. * @param __end End iterator input sequence, ignored. * @param __comp Comparator. * @param __num_threads Number of threads that are allowed to work on * this part. */ template void __parallel_sort_qs(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { _GLIBCXX_CALL(__n) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; // At least one element per processor. if (__num_threads > __n) __num_threads = static_cast<_ThreadIndex>(__n); __parallel_sort_qs_conquer( __begin, __begin + __n, __comp, __num_threads); } } //namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_QUICKSORT_H */ 8/parallel/omp_loop_static.h000064400000010010152526447520012057 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/omp_loop_static.h * @brief Parallelization of embarrassingly parallel execution by * means of an OpenMP for loop with static scheduling. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_OMP_LOOP_STATIC_H #define _GLIBCXX_PARALLEL_OMP_LOOP_STATIC_H 1 #include #include #include namespace __gnu_parallel { /** @brief Embarrassingly parallel algorithm for random access * iterators, using an OpenMP for loop with static scheduling. * * @param __begin Begin iterator of element sequence. * @param __end End iterator of element sequence. * @param __o User-supplied functor (comparator, predicate, adding * functor, ...). * @param __f Functor to @a process an element with __op (depends on * desired functionality, e. g. for std::for_each(), ...). * @param __r Functor to @a add a single __result to the already processed * __elements (depends on functionality). * @param __base Base value for reduction. * @param __output Pointer to position where final result is written to * @param __bound Maximum number of elements processed (e. g. for * std::count_n()). * @return User-supplied functor (that may contain a part of the result). */ template _Op __for_each_template_random_access_omp_loop_static(_RAIter __begin, _RAIter __end, _Op __o, _Fu& __f, _Red __r, _Result __base, _Result& __output, typename std::iterator_traits<_RAIter>::difference_type __bound) { typedef typename std::iterator_traits<_RAIter>::difference_type _DifferenceType; _DifferenceType __length = __end - __begin; _ThreadIndex __num_threads = std::min<_DifferenceType> (__get_max_threads(), __length); _Result *__thread_results; # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __thread_results = new _Result[__num_threads]; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __thread_results[__i] = _Result(); } _ThreadIndex __iam = omp_get_thread_num(); #pragma omp for schedule(static, _Settings::get().workstealing_chunk_size) for (_DifferenceType __pos = 0; __pos < __length; ++__pos) __thread_results[__iam] = __r(__thread_results[__iam], __f(__o, __begin+__pos)); } //parallel for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __output = __r(__output, __thread_results[__i]); delete [] __thread_results; // Points to last element processed (needed as return value for // some algorithms like transform). __f.finish_iterator = __begin + __length; return __o; } } // end namespace #endif /* _GLIBCXX_PARALLEL_OMP_LOOP_STATIC_H */ 8/parallel/par_loop.h000064400000010710152526447520010506 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/par_loop.h * @brief Parallelization of embarrassingly parallel execution by * means of equal splitting. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_PAR_LOOP_H #define _GLIBCXX_PARALLEL_PAR_LOOP_H 1 #include #include #include #include namespace __gnu_parallel { /** @brief Embarrassingly parallel algorithm for random access * iterators, using hand-crafted parallelization by equal splitting * the work. * * @param __begin Begin iterator of element sequence. * @param __end End iterator of element sequence. * @param __o User-supplied functor (comparator, predicate, adding * functor, ...) * @param __f Functor to "process" an element with __op (depends on * desired functionality, e. g. for std::for_each(), ...). * @param __r Functor to "add" a single __result to the already * processed elements (depends on functionality). * @param __base Base value for reduction. * @param __output Pointer to position where final result is written to * @param __bound Maximum number of elements processed (e. g. for * std::count_n()). * @return User-supplied functor (that may contain a part of the result). */ template _Op __for_each_template_random_access_ed(_RAIter __begin, _RAIter __end, _Op __o, _Fu& __f, _Red __r, _Result __base, _Result& __output, typename std::iterator_traits<_RAIter>::difference_type __bound) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; const _DifferenceType __length = __end - __begin; _Result *__thread_results; bool* __constructed; _ThreadIndex __num_threads = __gnu_parallel::min<_DifferenceType> (__get_max_threads(), __length); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __thread_results = static_cast<_Result*> (::operator new(__num_threads * sizeof(_Result))); __constructed = new bool[__num_threads]; } _ThreadIndex __iam = omp_get_thread_num(); // Neutral element. _Result* __reduct; _DifferenceType __start = __equally_split_point(__length, __num_threads, __iam), __stop = __equally_split_point(__length, __num_threads, __iam + 1); if (__start < __stop) { __reduct = new _Result(__f(__o, __begin + __start)); ++__start; __constructed[__iam] = true; } else __constructed[__iam] = false; for (; __start < __stop; ++__start) *__reduct = __r(*__reduct, __f(__o, __begin + __start)); if (__constructed[__iam]) { ::new(&__thread_results[__iam]) _Result(*__reduct); delete __reduct; } } //parallel for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) if (__constructed[__i]) { __output = __r(__output, __thread_results[__i]); __thread_results[__i].~_Result(); } // Points to last element processed (needed as return value for // some algorithms like transform). __f._M_finish_iterator = __begin + __length; ::operator delete(__thread_results); delete[] __constructed; return __o; } } // end namespace #endif /* _GLIBCXX_PARALLEL_PAR_LOOP_H */ 8/parallel/partition.h000064400000035161152526447520010713 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/partition.h * @brief Parallel implementation of std::partition(), * std::nth_element(), and std::partial_sort(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_PARTITION_H #define _GLIBCXX_PARALLEL_PARTITION_H 1 #include #include #include #include #include /** @brief Decide whether to declare certain variables volatile. */ #define _GLIBCXX_VOLATILE volatile namespace __gnu_parallel { /** @brief Parallel implementation of std::partition. * @param __begin Begin iterator of input sequence to split. * @param __end End iterator of input sequence to split. * @param __pred Partition predicate, possibly including some kind * of pivot. * @param __num_threads Maximum number of threads to use for this task. * @return Number of elements not fulfilling the predicate. */ template typename std::iterator_traits<_RAIter>::difference_type __parallel_partition(_RAIter __begin, _RAIter __end, _Predicate __pred, _ThreadIndex __num_threads) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; _GLIBCXX_CALL(__n) const _Settings& __s = _Settings::get(); // shared _GLIBCXX_VOLATILE _DifferenceType __left = 0, __right = __n - 1, __dist = __n, __leftover_left, __leftover_right, __leftnew, __rightnew; // just 0 or 1, but int to allow atomic operations int* __reserved_left = 0, * __reserved_right = 0; _DifferenceType __chunk_size = __s.partition_chunk_size; //at least two chunks per thread if (__dist >= 2 * __num_threads * __chunk_size) # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __reserved_left = new int[__num_threads]; __reserved_right = new int[__num_threads]; if (__s.partition_chunk_share > 0.0) __chunk_size = std::max<_DifferenceType> (__s.partition_chunk_size, (double)__n * __s.partition_chunk_share / (double)__num_threads); else __chunk_size = __s.partition_chunk_size; } while (__dist >= 2 * __num_threads * __chunk_size) { # pragma omp single { _DifferenceType __num_chunks = __dist / __chunk_size; for (_ThreadIndex __r = 0; __r < __num_threads; ++__r) { __reserved_left [__r] = 0; // false __reserved_right[__r] = 0; // false } __leftover_left = 0; __leftover_right = 0; } //implicit barrier // Private. _DifferenceType __thread_left, __thread_left_border, __thread_right, __thread_right_border; __thread_left = __left + 1; // Just to satisfy the condition below. __thread_left_border = __thread_left - 1; __thread_right = __n - 1; // Just to satisfy the condition below. __thread_right_border = __thread_right + 1; bool __iam_finished = false; while (!__iam_finished) { if (__thread_left > __thread_left_border) { _DifferenceType __former_dist = __fetch_and_add(&__dist, -__chunk_size); if (__former_dist < __chunk_size) { __fetch_and_add(&__dist, __chunk_size); __iam_finished = true; break; } else { __thread_left = __fetch_and_add(&__left, __chunk_size); __thread_left_border = __thread_left + (__chunk_size - 1); } } if (__thread_right < __thread_right_border) { _DifferenceType __former_dist = __fetch_and_add(&__dist, -__chunk_size); if (__former_dist < __chunk_size) { __fetch_and_add(&__dist, __chunk_size); __iam_finished = true; break; } else { __thread_right = __fetch_and_add(&__right, -__chunk_size); __thread_right_border = __thread_right - (__chunk_size - 1); } } // Swap as usual. while (__thread_left < __thread_right) { while (__pred(__begin[__thread_left]) && __thread_left <= __thread_left_border) ++__thread_left; while (!__pred(__begin[__thread_right]) && __thread_right >= __thread_right_border) --__thread_right; if (__thread_left > __thread_left_border || __thread_right < __thread_right_border) // Fetch new chunk(__s). break; std::iter_swap(__begin + __thread_left, __begin + __thread_right); ++__thread_left; --__thread_right; } } // Now swap the leftover chunks to the right places. if (__thread_left <= __thread_left_border) # pragma omp atomic ++__leftover_left; if (__thread_right >= __thread_right_border) # pragma omp atomic ++__leftover_right; # pragma omp barrier _DifferenceType __leftold = __left, __leftnew = __left - __leftover_left * __chunk_size, __rightold = __right, __rightnew = __right + __leftover_right * __chunk_size; // <=> __thread_left_border + (__chunk_size - 1) >= __leftnew if (__thread_left <= __thread_left_border && __thread_left_border >= __leftnew) { // Chunk already in place, reserve spot. __reserved_left[(__left - (__thread_left_border + 1)) / __chunk_size] = 1; } // <=> __thread_right_border - (__chunk_size - 1) <= __rightnew if (__thread_right >= __thread_right_border && __thread_right_border <= __rightnew) { // Chunk already in place, reserve spot. __reserved_right[((__thread_right_border - 1) - __right) / __chunk_size] = 1; } # pragma omp barrier if (__thread_left <= __thread_left_border && __thread_left_border < __leftnew) { // Find spot and swap. _DifferenceType __swapstart = -1; for (int __r = 0; __r < __leftover_left; ++__r) if (__reserved_left[__r] == 0 && __compare_and_swap(&(__reserved_left[__r]), 0, 1)) { __swapstart = __leftold - (__r + 1) * __chunk_size; break; } #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__swapstart != -1); #endif std::swap_ranges(__begin + __thread_left_border - (__chunk_size - 1), __begin + __thread_left_border + 1, __begin + __swapstart); } if (__thread_right >= __thread_right_border && __thread_right_border > __rightnew) { // Find spot and swap _DifferenceType __swapstart = -1; for (int __r = 0; __r < __leftover_right; ++__r) if (__reserved_right[__r] == 0 && __compare_and_swap(&(__reserved_right[__r]), 0, 1)) { __swapstart = __rightold + __r * __chunk_size + 1; break; } #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__swapstart != -1); #endif std::swap_ranges(__begin + __thread_right_border, __begin + __thread_right_border + __chunk_size, __begin + __swapstart); } #if _GLIBCXX_PARALLEL_ASSERTIONS # pragma omp barrier # pragma omp single { for (_DifferenceType __r = 0; __r < __leftover_left; ++__r) _GLIBCXX_PARALLEL_ASSERT(__reserved_left[__r] == 1); for (_DifferenceType __r = 0; __r < __leftover_right; ++__r) _GLIBCXX_PARALLEL_ASSERT(__reserved_right[__r] == 1); } #endif __left = __leftnew; __right = __rightnew; __dist = __right - __left + 1; } # pragma omp flush(__left, __right) } // end "recursion" //parallel _DifferenceType __final_left = __left, __final_right = __right; while (__final_left < __final_right) { // Go right until key is geq than pivot. while (__pred(__begin[__final_left]) && __final_left < __final_right) ++__final_left; // Go left until key is less than pivot. while (!__pred(__begin[__final_right]) && __final_left < __final_right) --__final_right; if (__final_left == __final_right) break; std::iter_swap(__begin + __final_left, __begin + __final_right); ++__final_left; --__final_right; } // All elements on the left side are < piv, all elements on the // right are >= piv delete[] __reserved_left; delete[] __reserved_right; // Element "between" __final_left and __final_right might not have // been regarded yet if (__final_left < __n && !__pred(__begin[__final_left])) // Really swapped. return __final_left; else return __final_left + 1; } /** * @brief Parallel implementation of std::nth_element(). * @param __begin Begin iterator of input sequence. * @param __nth _Iterator of element that must be in position afterwards. * @param __end End iterator of input sequence. * @param __comp Comparator. */ template void __parallel_nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end, _Compare __comp) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _GLIBCXX_CALL(__end - __begin) _RAIter __split; _RandomNumber __rng; const _Settings& __s = _Settings::get(); _DifferenceType __minimum_length = std::max<_DifferenceType>(2, std::max(__s.nth_element_minimal_n, __s.partition_minimal_n)); // Break if input range to small. while (static_cast<_SequenceIndex>(__end - __begin) >= __minimum_length) { _DifferenceType __n = __end - __begin; _RAIter __pivot_pos = __begin + __rng(__n); // Swap __pivot_pos value to end. if (__pivot_pos != (__end - 1)) std::iter_swap(__pivot_pos, __end - 1); __pivot_pos = __end - 1; // _Compare must have first_value_type, second_value_type, // result_type // _Compare == // __gnu_parallel::_Lexicographic > // __pivot_pos == std::pair* __gnu_parallel::__binder2nd<_Compare, _ValueType, _ValueType, bool> __pred(__comp, *__pivot_pos); // Divide, leave pivot unchanged in last place. _RAIter __split_pos1, __split_pos2; __split_pos1 = __begin + __parallel_partition(__begin, __end - 1, __pred, __get_max_threads()); // Left side: < __pivot_pos; __right side: >= __pivot_pos // Swap pivot back to middle. if (__split_pos1 != __pivot_pos) std::iter_swap(__split_pos1, __pivot_pos); __pivot_pos = __split_pos1; // In case all elements are equal, __split_pos1 == 0 if ((__split_pos1 + 1 - __begin) < (__n >> 7) || (__end - __split_pos1) < (__n >> 7)) { // Very unequal split, one part smaller than one 128th // elements not strictly larger than the pivot. __gnu_parallel::__unary_negate<__gnu_parallel:: __binder1st<_Compare, _ValueType, _ValueType, bool>, _ValueType> __pred(__gnu_parallel::__binder1st<_Compare, _ValueType, _ValueType, bool>(__comp, *__pivot_pos)); // Find other end of pivot-equal range. __split_pos2 = __gnu_sequential::partition(__split_pos1 + 1, __end, __pred); } else // Only skip the pivot. __split_pos2 = __split_pos1 + 1; // Compare iterators. if (__split_pos2 <= __nth) __begin = __split_pos2; else if (__nth < __split_pos1) __end = __split_pos1; else break; } // Only at most _Settings::partition_minimal_n __elements __left. __gnu_sequential::nth_element(__begin, __nth, __end, __comp); } /** @brief Parallel implementation of std::partial_sort(). * @param __begin Begin iterator of input sequence. * @param __middle Sort until this position. * @param __end End iterator of input sequence. * @param __comp Comparator. */ template void __parallel_partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end, _Compare __comp) { __parallel_nth_element(__begin, __middle, __end, __comp); std::sort(__begin, __middle, __comp); } } //namespace __gnu_parallel #undef _GLIBCXX_VOLATILE #endif /* _GLIBCXX_PARALLEL_PARTITION_H */ 8/parallel/numericfwd.h000064400000016514152526447520011046 0ustar00// Forward declarations -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/numericfwd.h * This file is a GNU parallel extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PARALLEL_NUMERICFWD_H #define _GLIBCXX_PARALLEL_NUMERICFWD_H 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { template _Tp accumulate(_IIter, _IIter, _Tp); template _Tp accumulate(_IIter, _IIter, _Tp, __gnu_parallel::sequential_tag); template _Tp accumulate(_IIter, _IIter, _Tp, __gnu_parallel::_Parallelism); template _Tp __accumulate_switch(_IIter, _IIter, _Tp, _Tag); template _Tp accumulate(_IIter, _IIter, _Tp, _BinaryOper); template _Tp accumulate(_IIter, _IIter, _Tp, _BinaryOper, __gnu_parallel::sequential_tag); template _Tp accumulate(_IIter, _IIter, _Tp, _BinaryOper, __gnu_parallel::_Parallelism); template _Tp __accumulate_switch(_IIter, _IIter, _Tp, _BinaryOper, _Tag); template _Tp __accumulate_switch(_RAIter, _RAIter, _Tp, _BinaryOper, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_unbalanced); template _OIter adjacent_difference(_IIter, _IIter, _OIter); template _OIter adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper); template _OIter adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag); template _OIter adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::sequential_tag); template _OIter adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::_Parallelism); template _OIter adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::_Parallelism); template _OIter __adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2); template _OIter __adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_unbalanced); template _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp); template _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, __gnu_parallel::sequential_tag); template _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, __gnu_parallel::_Parallelism); template _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, _BinaryFunction2); template _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, _BinaryFunction2, __gnu_parallel::sequential_tag); template _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, BinaryFunction1, BinaryFunction2, __gnu_parallel::_Parallelism); template _Tp __inner_product_switch(_RAIter1, _RAIter1, _RAIter2, _Tp, BinaryFunction1, BinaryFunction2, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism = __gnu_parallel::parallel_unbalanced); template _Tp __inner_product_switch(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, _BinaryFunction2, _Tag1, _Tag2); template _OIter partial_sum(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag); template _OIter partial_sum(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::sequential_tag); template _OIter partial_sum(_IIter, _IIter, _OIter __result); template _OIter partial_sum(_IIter, _IIter, _OIter, _BinaryOper); template _OIter __partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2); template _OIter __partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, random_access_iterator_tag, random_access_iterator_tag); } // end namespace } // end namespace #endif /* _GLIBCXX_PARALLEL_NUMERICFWD_H */ 8/parallel/algo.h000064400000234236152526447520007630 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/algo.h * @brief Parallel STL function calls corresponding to the stl_algo.h header. * * The functions defined here mainly do case switches and * call the actual parallelized versions in other files. * Inlining policy: Functions that basically only contain one function call, * are declared inline. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_ALGO_H #define _GLIBCXX_PARALLEL_ALGO_H 1 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { // Sequential fallback template inline _Function for_each(_IIter __begin, _IIter __end, _Function __f, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::for_each(__begin, __end, __f); } // Sequential fallback for input iterator case template inline _Function __for_each_switch(_IIter __begin, _IIter __end, _Function __f, _IteratorTag) { return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template _Function __for_each_switch(_RAIter __begin, _RAIter __end, _Function __f, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().for_each_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy; __gnu_parallel::__for_each_selector<_RAIter> __functionality; return __gnu_parallel:: __for_each_template_random_access( __begin, __end, __f, __functionality, __gnu_parallel::_DummyReduct(), true, __dummy, -1, __parallelism_tag); } else return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); } // Public interface template inline _Function for_each(_Iterator __begin, _Iterator __end, _Function __f, __gnu_parallel::_Parallelism __parallelism_tag) { return __for_each_switch(__begin, __end, __f, std::__iterator_category(__begin), __parallelism_tag); } template inline _Function for_each(_Iterator __begin, _Iterator __end, _Function __f) { return __for_each_switch(__begin, __end, __f, std::__iterator_category(__begin)); } // Sequential fallback template inline _IIter find(_IIter __begin, _IIter __end, const _Tp& __val, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::find(__begin, __end, __val); } // Sequential fallback for input iterator case template inline _IIter __find_switch(_IIter __begin, _IIter __end, const _Tp& __val, _IteratorTag) { return _GLIBCXX_STD_A::find(__begin, __end, __val); } // Parallel find for random access iterators template _RAIter __find_switch(_RAIter __begin, _RAIter __end, const _Tp& __val, random_access_iterator_tag) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; if (_GLIBCXX_PARALLEL_CONDITION(true)) { __gnu_parallel::__binder2nd<__gnu_parallel::_EqualTo<_ValueType, const _Tp&>, _ValueType, const _Tp&, bool> __comp(__gnu_parallel::_EqualTo<_ValueType, const _Tp&>(), __val); return __gnu_parallel::__find_template( __begin, __end, __begin, __comp, __gnu_parallel::__find_if_selector()).first; } else return _GLIBCXX_STD_A::find(__begin, __end, __val); } // Public interface template inline _IIter find(_IIter __begin, _IIter __end, const _Tp& __val) { return __find_switch(__begin, __end, __val, std::__iterator_category(__begin)); } // Sequential fallback template inline _IIter find_if(_IIter __begin, _IIter __end, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); } // Sequential fallback for input iterator case template inline _IIter __find_if_switch(_IIter __begin, _IIter __end, _Predicate __pred, _IteratorTag) { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); } // Parallel find_if for random access iterators template _RAIter __find_if_switch(_RAIter __begin, _RAIter __end, _Predicate __pred, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) return __gnu_parallel::__find_template(__begin, __end, __begin, __pred, __gnu_parallel:: __find_if_selector()).first; else return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); } // Public interface template inline _IIter find_if(_IIter __begin, _IIter __end, _Predicate __pred) { return __find_if_switch(__begin, __end, __pred, std::__iterator_category(__begin)); } // Sequential fallback template inline _IIter find_first_of(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::find_first_of(__begin1, __end1, __begin2, __end2); } // Sequential fallback template inline _IIter find_first_of(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::find_first_of( __begin1, __end1, __begin2, __end2, __comp); } // Sequential fallback for input iterator type template inline _IIter __find_first_of_switch(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, _IteratorTag1, _IteratorTag2) { return find_first_of(__begin1, __end1, __begin2, __end2, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template inline _RAIter __find_first_of_switch(_RAIter __begin1, _RAIter __end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate __comp, random_access_iterator_tag, _IteratorTag) { return __gnu_parallel:: __find_template(__begin1, __end1, __begin1, __comp, __gnu_parallel::__find_first_of_selector <_FIterator>(__begin2, __end2)).first; } // Sequential fallback for input iterator type template inline _IIter __find_first_of_switch(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate __comp, _IteratorTag1, _IteratorTag2) { return find_first_of(__begin1, __end1, __begin2, __end2, __comp, __gnu_parallel::sequential_tag()); } // Public interface template inline _IIter find_first_of(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate __comp) { return __find_first_of_switch(__begin1, __end1, __begin2, __end2, __comp, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } // Public interface, insert default comparator template inline _IIter find_first_of(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2) { typedef typename std::iterator_traits<_IIter>::value_type _IValueType; typedef typename std::iterator_traits<_FIterator>::value_type _FValueType; return __gnu_parallel::find_first_of(__begin1, __end1, __begin2, __end2, __gnu_parallel::_EqualTo<_IValueType, _FValueType>()); } // Sequential fallback template inline _OutputIterator unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out); } // Sequential fallback template inline _OutputIterator unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out, __pred); } // Sequential fallback for input iterator case template inline _OutputIterator __unique_copy_switch(_IIter __begin, _IIter __last, _OutputIterator __out, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred); } // Parallel unique_copy for random access iterators template RandomAccessOutputIterator __unique_copy_switch(_RAIter __begin, _RAIter __last, RandomAccessOutputIterator __out, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__last - __begin) > __gnu_parallel::_Settings::get().unique_copy_minimal_n)) return __gnu_parallel::__parallel_unique_copy( __begin, __last, __out, __pred); else return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred); } // Public interface template inline _OutputIterator unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter>::value_type _ValueType; return __unique_copy_switch( __begin1, __end1, __out, equal_to<_ValueType>(), std::__iterator_category(__begin1), std::__iterator_category(__out)); } // Public interface template inline _OutputIterator unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out, _Predicate __pred) { return __unique_copy_switch( __begin1, __end1, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__out)); } // Sequential fallback template inline _OutputIterator set_union(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_union( __begin1, __end1, __begin2, __end2, __out); } // Sequential fallback template inline _OutputIterator set_union(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_union(__begin1, __end1, __begin2, __end2, __out, __pred); } // Sequential fallback for input iterator case template inline _OutputIterator __set_union_switch( _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::set_union(__begin1, __end1, __begin2, __end2, __result, __pred); } // Parallel set_union for random access iterators template _Output_RAIter __set_union_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().set_union_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().set_union_minimal_n)) return __gnu_parallel::__parallel_set_union( __begin1, __end1, __begin2, __end2, __result, __pred); else return _GLIBCXX_STD_A::set_union(__begin1, __end1, __begin2, __end2, __result, __pred); } // Public interface template inline _OutputIterator set_union(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __set_union_switch( __begin1, __end1, __begin2, __end2, __out, __gnu_parallel::_Less<_ValueType1, _ValueType2>(), std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Public interface template inline _OutputIterator set_union(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred) { return __set_union_switch( __begin1, __end1, __begin2, __end2, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Sequential fallback. template inline _OutputIterator set_intersection(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1, __begin2, __end2, __out); } // Sequential fallback. template inline _OutputIterator set_intersection(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_intersection( __begin1, __end1, __begin2, __end2, __out, __pred); } // Sequential fallback for input iterator case template inline _OutputIterator __set_intersection_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1, __begin2, __end2, __result, __pred); } // Parallel set_intersection for random access iterators template _Output_RAIter __set_intersection_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().set_union_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().set_union_minimal_n)) return __gnu_parallel::__parallel_set_intersection( __begin1, __end1, __begin2, __end2, __result, __pred); else return _GLIBCXX_STD_A::set_intersection( __begin1, __end1, __begin2, __end2, __result, __pred); } // Public interface template inline _OutputIterator set_intersection(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __set_intersection_switch( __begin1, __end1, __begin2, __end2, __out, __gnu_parallel::_Less<_ValueType1, _ValueType2>(), std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } template inline _OutputIterator set_intersection(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred) { return __set_intersection_switch( __begin1, __end1, __begin2, __end2, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Sequential fallback template inline _OutputIterator set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_symmetric_difference( __begin1, __end1, __begin2, __end2, __out); } // Sequential fallback template inline _OutputIterator set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_symmetric_difference( __begin1, __end1, __begin2, __end2, __out, __pred); } // Sequential fallback for input iterator case template inline _OutputIterator __set_symmetric_difference_switch( _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::set_symmetric_difference( __begin1, __end1, __begin2, __end2, __result, __pred); } // Parallel set_symmetric_difference for random access iterators template _Output_RAIter __set_symmetric_difference_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n)) return __gnu_parallel::__parallel_set_symmetric_difference( __begin1, __end1, __begin2, __end2, __result, __pred); else return _GLIBCXX_STD_A::set_symmetric_difference( __begin1, __end1, __begin2, __end2, __result, __pred); } // Public interface. template inline _OutputIterator set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __set_symmetric_difference_switch( __begin1, __end1, __begin2, __end2, __out, __gnu_parallel::_Less<_ValueType1, _ValueType2>(), std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Public interface. template inline _OutputIterator set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred) { return __set_symmetric_difference_switch( __begin1, __end1, __begin2, __end2, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Sequential fallback. template inline _OutputIterator set_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_difference( __begin1,__end1, __begin2, __end2, __out); } // Sequential fallback. template inline _OutputIterator set_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_difference(__begin1, __end1, __begin2, __end2, __out, __pred); } // Sequential fallback for input iterator case. template inline _OutputIterator __set_difference_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::set_difference( __begin1, __end1, __begin2, __end2, __result, __pred); } // Parallel set_difference for random access iterators template _Output_RAIter __set_difference_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().set_difference_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().set_difference_minimal_n)) return __gnu_parallel::__parallel_set_difference( __begin1, __end1, __begin2, __end2, __result, __pred); else return _GLIBCXX_STD_A::set_difference( __begin1, __end1, __begin2, __end2, __result, __pred); } // Public interface template inline _OutputIterator set_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __set_difference_switch( __begin1, __end1, __begin2, __end2, __out, __gnu_parallel::_Less<_ValueType1, _ValueType2>(), std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Public interface template inline _OutputIterator set_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred) { return __set_difference_switch( __begin1, __end1, __begin2, __end2, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Sequential fallback template inline _FIterator adjacent_find(_FIterator __begin, _FIterator __end, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::adjacent_find(__begin, __end); } // Sequential fallback template inline _FIterator adjacent_find(_FIterator __begin, _FIterator __end, _BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::adjacent_find(__begin, __end, __binary_pred); } // Parallel algorithm for random access iterators template _RAIter __adjacent_find_switch(_RAIter __begin, _RAIter __end, random_access_iterator_tag) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; if (_GLIBCXX_PARALLEL_CONDITION(true)) { _RAIter __spot = __gnu_parallel:: __find_template( __begin, __end - 1, __begin, equal_to<_ValueType>(), __gnu_parallel::__adjacent_find_selector()) .first; if (__spot == (__end - 1)) return __end; else return __spot; } else return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case template inline _FIterator __adjacent_find_switch(_FIterator __begin, _FIterator __end, _IteratorTag) { return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); } // Public interface template inline _FIterator adjacent_find(_FIterator __begin, _FIterator __end) { return __adjacent_find_switch(__begin, __end, std::__iterator_category(__begin)); } // Sequential fallback for input iterator case template inline _FIterator __adjacent_find_switch(_FIterator __begin, _FIterator __end, _BinaryPredicate __pred, _IteratorTag) { return adjacent_find(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template _RAIter __adjacent_find_switch(_RAIter __begin, _RAIter __end, _BinaryPredicate __pred, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) return __gnu_parallel::__find_template(__begin, __end, __begin, __pred, __gnu_parallel:: __adjacent_find_selector()).first; else return adjacent_find(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Public interface template inline _FIterator adjacent_find(_FIterator __begin, _FIterator __end, _BinaryPredicate __pred) { return __adjacent_find_switch(__begin, __end, __pred, std::__iterator_category(__begin)); } // Sequential fallback template inline typename iterator_traits<_IIter>::difference_type count(_IIter __begin, _IIter __end, const _Tp& __value, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::count(__begin, __end, __value); } // Parallel code for random access iterators template typename iterator_traits<_RAIter>::difference_type __count_switch(_RAIter __begin, _RAIter __end, const _Tp& __value, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; typedef __gnu_parallel::_SequenceIndex _SequenceIndex; if (_GLIBCXX_PARALLEL_CONDITION( static_cast<_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().count_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { __gnu_parallel::__count_selector<_RAIter, _DifferenceType> __functionality; _DifferenceType __res = 0; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __value, __functionality, std::plus<_SequenceIndex>(), __res, __res, -1, __parallelism_tag); return __res; } else return count(__begin, __end, __value, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case. template inline typename iterator_traits<_IIter>::difference_type __count_switch(_IIter __begin, _IIter __end, const _Tp& __value, _IteratorTag) { return count(__begin, __end, __value, __gnu_parallel::sequential_tag()); } // Public interface. template inline typename iterator_traits<_IIter>::difference_type count(_IIter __begin, _IIter __end, const _Tp& __value, __gnu_parallel::_Parallelism __parallelism_tag) { return __count_switch(__begin, __end, __value, std::__iterator_category(__begin), __parallelism_tag); } template inline typename iterator_traits<_IIter>::difference_type count(_IIter __begin, _IIter __end, const _Tp& __value) { return __count_switch(__begin, __end, __value, std::__iterator_category(__begin)); } // Sequential fallback. template inline typename iterator_traits<_IIter>::difference_type count_if(_IIter __begin, _IIter __end, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::count_if(__begin, __end, __pred); } // Parallel count_if for random access iterators template typename iterator_traits<_RAIter>::difference_type __count_if_switch(_RAIter __begin, _RAIter __end, _Predicate __pred, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; typedef __gnu_parallel::_SequenceIndex _SequenceIndex; if (_GLIBCXX_PARALLEL_CONDITION( static_cast<_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().count_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { _DifferenceType __res = 0; __gnu_parallel:: __count_if_selector<_RAIter, _DifferenceType> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __pred, __functionality, std::plus<_SequenceIndex>(), __res, __res, -1, __parallelism_tag); return __res; } else return count_if(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case. template inline typename iterator_traits<_IIter>::difference_type __count_if_switch(_IIter __begin, _IIter __end, _Predicate __pred, _IteratorTag) { return count_if(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Public interface. template inline typename iterator_traits<_IIter>::difference_type count_if(_IIter __begin, _IIter __end, _Predicate __pred, __gnu_parallel::_Parallelism __parallelism_tag) { return __count_if_switch(__begin, __end, __pred, std::__iterator_category(__begin), __parallelism_tag); } template inline typename iterator_traits<_IIter>::difference_type count_if(_IIter __begin, _IIter __end, _Predicate __pred) { return __count_if_switch(__begin, __end, __pred, std::__iterator_category(__begin)); } // Sequential fallback. template inline _FIterator1 search(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::search(__begin1, __end1, __begin2, __end2); } // Parallel algorithm for random access iterator template _RAIter1 __search_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, random_access_iterator_tag, random_access_iterator_tag) { typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_RAIter2>::value_type _ValueType2; if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().search_minimal_n)) return __gnu_parallel:: __search_template( __begin1, __end1, __begin2, __end2, __gnu_parallel::_EqualTo<_ValueType1, _ValueType2>()); else return search(__begin1, __end1, __begin2, __end2, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case template inline _FIterator1 __search_switch(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, _IteratorTag1, _IteratorTag2) { return search(__begin1, __end1, __begin2, __end2, __gnu_parallel::sequential_tag()); } // Public interface. template inline _FIterator1 search(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2) { return __search_switch(__begin1, __end1, __begin2, __end2, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } // Public interface. template inline _FIterator1 search(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, _BinaryPredicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::search( __begin1, __end1, __begin2, __end2, __pred); } // Parallel algorithm for random access iterator. template _RAIter1 __search_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().search_minimal_n)) return __gnu_parallel::__search_template(__begin1, __end1, __begin2, __end2, __pred); else return search(__begin1, __end1, __begin2, __end2, __pred, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case template inline _FIterator1 __search_switch(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2) { return search(__begin1, __end1, __begin2, __end2, __pred, __gnu_parallel::sequential_tag()); } // Public interface template inline _FIterator1 search(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, _BinaryPredicate __pred) { return __search_switch(__begin1, __end1, __begin2, __end2, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } // Sequential fallback template inline _FIterator search_n(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val); } // Sequential fallback template inline _FIterator search_n(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::search_n( __begin, __end, __count, __val, __binary_pred); } // Public interface. template inline _FIterator search_n(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return __gnu_parallel::search_n(__begin, __end, __count, __val, __gnu_parallel::_EqualTo<_ValueType, _Tp>()); } // Parallel algorithm for random access iterators. template _RAIter __search_n_switch(_RAIter __begin, _RAIter __end, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().search_minimal_n)) { __gnu_parallel::_PseudoSequence<_Tp, _Integer> __ps(__val, __count); return __gnu_parallel::__search_template( __begin, __end, __ps.begin(), __ps.end(), __binary_pred); } else return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val, __binary_pred); } // Sequential fallback for input iterator case. template inline _FIterator __search_n_switch(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred, _IteratorTag) { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val, __binary_pred); } // Public interface. template inline _FIterator search_n(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred) { return __search_n_switch(__begin, __end, __count, __val, __binary_pred, std::__iterator_category(__begin)); } // Sequential fallback. template inline _OutputIterator transform(_IIter __begin, _IIter __end, _OutputIterator __result, _UnaryOperation __unary_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::transform(__begin, __end, __result, __unary_op); } // Parallel unary transform for random access iterators. template _RAIter2 __transform1_switch(_RAIter1 __begin, _RAIter1 __end, _RAIter2 __result, _UnaryOperation __unary_op, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().transform_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy = true; typedef __gnu_parallel::_IteratorPair<_RAIter1, _RAIter2, random_access_iterator_tag> _ItTrip; _ItTrip __begin_pair(__begin, __result), __end_pair(__end, __result + (__end - __begin)); __gnu_parallel::__transform1_selector<_ItTrip> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin_pair, __end_pair, __unary_op, __functionality, __gnu_parallel::_DummyReduct(), __dummy, __dummy, -1, __parallelism_tag); return __functionality._M_finish_iterator; } else return transform(__begin, __end, __result, __unary_op, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case. template inline _RAIter2 __transform1_switch(_RAIter1 __begin, _RAIter1 __end, _RAIter2 __result, _UnaryOperation __unary_op, _IteratorTag1, _IteratorTag2) { return transform(__begin, __end, __result, __unary_op, __gnu_parallel::sequential_tag()); } // Public interface. template inline _OutputIterator transform(_IIter __begin, _IIter __end, _OutputIterator __result, _UnaryOperation __unary_op, __gnu_parallel::_Parallelism __parallelism_tag) { return __transform1_switch(__begin, __end, __result, __unary_op, std::__iterator_category(__begin), std::__iterator_category(__result), __parallelism_tag); } template inline _OutputIterator transform(_IIter __begin, _IIter __end, _OutputIterator __result, _UnaryOperation __unary_op) { return __transform1_switch(__begin, __end, __result, __unary_op, std::__iterator_category(__begin), std::__iterator_category(__result)); } // Sequential fallback template inline _OutputIterator transform(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator __result, _BinaryOperation __binary_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::transform(__begin1, __end1, __begin2, __result, __binary_op); } // Parallel binary transform for random access iterators. template _RAIter3 __transform2_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter3 __result, _BinaryOperation __binary_op, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( (__end1 - __begin1) >= __gnu_parallel::_Settings::get().transform_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy = true; typedef __gnu_parallel::_IteratorTriple<_RAIter1, _RAIter2, _RAIter3, random_access_iterator_tag> _ItTrip; _ItTrip __begin_triple(__begin1, __begin2, __result), __end_triple(__end1, __begin2 + (__end1 - __begin1), __result + (__end1 - __begin1)); __gnu_parallel::__transform2_selector<_ItTrip> __functionality; __gnu_parallel:: __for_each_template_random_access(__begin_triple, __end_triple, __binary_op, __functionality, __gnu_parallel::_DummyReduct(), __dummy, __dummy, -1, __parallelism_tag); return __functionality._M_finish_iterator; } else return transform(__begin1, __end1, __begin2, __result, __binary_op, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case. template inline _OutputIterator __transform2_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator __result, _BinaryOperation __binary_op, _Tag1, _Tag2, _Tag3) { return transform(__begin1, __end1, __begin2, __result, __binary_op, __gnu_parallel::sequential_tag()); } // Public interface. template inline _OutputIterator transform(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator __result, _BinaryOperation __binary_op, __gnu_parallel::_Parallelism __parallelism_tag) { return __transform2_switch( __begin1, __end1, __begin2, __result, __binary_op, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__result), __parallelism_tag); } template inline _OutputIterator transform(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator __result, _BinaryOperation __binary_op) { return __transform2_switch( __begin1, __end1, __begin2, __result, __binary_op, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__result)); } // Sequential fallback template inline void replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value, const _Tp& __new_value, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::replace(__begin, __end, __old_value, __new_value); } // Sequential fallback for input iterator case template inline void __replace_switch(_FIterator __begin, _FIterator __end, const _Tp& __old_value, const _Tp& __new_value, _IteratorTag) { replace(__begin, __end, __old_value, __new_value, __gnu_parallel::sequential_tag()); } // Parallel replace for random access iterators template inline void __replace_switch(_RAIter __begin, _RAIter __end, const _Tp& __old_value, const _Tp& __new_value, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { // XXX parallel version is where? replace(__begin, __end, __old_value, __new_value, __gnu_parallel::sequential_tag()); } // Public interface template inline void replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value, const _Tp& __new_value, __gnu_parallel::_Parallelism __parallelism_tag) { __replace_switch(__begin, __end, __old_value, __new_value, std::__iterator_category(__begin), __parallelism_tag); } template inline void replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value, const _Tp& __new_value) { __replace_switch(__begin, __end, __old_value, __new_value, std::__iterator_category(__begin)); } // Sequential fallback template inline void replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred, const _Tp& __new_value, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::replace_if(__begin, __end, __pred, __new_value); } // Sequential fallback for input iterator case template inline void __replace_if_switch(_FIterator __begin, _FIterator __end, _Predicate __pred, const _Tp& __new_value, _IteratorTag) { replace_if(__begin, __end, __pred, __new_value, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template void __replace_if_switch(_RAIter __begin, _RAIter __end, _Predicate __pred, const _Tp& __new_value, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().replace_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy; __gnu_parallel:: __replace_if_selector<_RAIter, _Predicate, _Tp> __functionality(__new_value); __gnu_parallel:: __for_each_template_random_access( __begin, __end, __pred, __functionality, __gnu_parallel::_DummyReduct(), true, __dummy, -1, __parallelism_tag); } else replace_if(__begin, __end, __pred, __new_value, __gnu_parallel::sequential_tag()); } // Public interface. template inline void replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred, const _Tp& __new_value, __gnu_parallel::_Parallelism __parallelism_tag) { __replace_if_switch(__begin, __end, __pred, __new_value, std::__iterator_category(__begin), __parallelism_tag); } template inline void replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred, const _Tp& __new_value) { __replace_if_switch(__begin, __end, __pred, __new_value, std::__iterator_category(__begin)); } // Sequential fallback template inline void generate(_FIterator __begin, _FIterator __end, _Generator __gen, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::generate(__begin, __end, __gen); } // Sequential fallback for input iterator case. template inline void __generate_switch(_FIterator __begin, _FIterator __end, _Generator __gen, _IteratorTag) { generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template void __generate_switch(_RAIter __begin, _RAIter __end, _Generator __gen, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().generate_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy; __gnu_parallel::__generate_selector<_RAIter> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __gen, __functionality, __gnu_parallel::_DummyReduct(), true, __dummy, -1, __parallelism_tag); } else generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); } // Public interface. template inline void generate(_FIterator __begin, _FIterator __end, _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag) { __generate_switch(__begin, __end, __gen, std::__iterator_category(__begin), __parallelism_tag); } template inline void generate(_FIterator __begin, _FIterator __end, _Generator __gen) { __generate_switch(__begin, __end, __gen, std::__iterator_category(__begin)); } // Sequential fallback. template inline _OutputIterator generate_n(_OutputIterator __begin, _Size __n, _Generator __gen, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::generate_n(__begin, __n, __gen); } // Sequential fallback for input iterator case. template inline _OutputIterator __generate_n_switch(_OutputIterator __begin, _Size __n, _Generator __gen, _IteratorTag) { return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template inline _RAIter __generate_n_switch(_RAIter __begin, _Size __n, _Generator __gen, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { // XXX parallel version is where? return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag()); } // Public interface. template inline _OutputIterator generate_n(_OutputIterator __begin, _Size __n, _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag) { return __generate_n_switch(__begin, __n, __gen, std::__iterator_category(__begin), __parallelism_tag); } template inline _OutputIterator generate_n(_OutputIterator __begin, _Size __n, _Generator __gen) { return __generate_n_switch(__begin, __n, __gen, std::__iterator_category(__begin)); } // Sequential fallback. template inline void random_shuffle(_RAIter __begin, _RAIter __end, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::random_shuffle(__begin, __end); } // Sequential fallback. template inline void random_shuffle(_RAIter __begin, _RAIter __end, _RandomNumberGenerator& __rand, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::random_shuffle(__begin, __end, __rand); } /** @brief Functor wrapper for std::rand(). */ template struct _CRandNumber { int operator()(int __limit) { return rand() % __limit; } }; // Fill in random number generator. template inline void random_shuffle(_RAIter __begin, _RAIter __end) { _CRandNumber<> __r; // Parallelization still possible. __gnu_parallel::random_shuffle(__begin, __end, __r); } // Parallel algorithm for random access iterators. template void random_shuffle(_RAIter __begin, _RAIter __end, #if __cplusplus >= 201103L _RandomNumberGenerator&& __rand) #else _RandomNumberGenerator& __rand) #endif { if (__begin == __end) return; if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().random_shuffle_minimal_n)) __gnu_parallel::__parallel_random_shuffle(__begin, __end, __rand); else __gnu_parallel::__sequential_random_shuffle(__begin, __end, __rand); } // Sequential fallback. template inline _FIterator partition(_FIterator __begin, _FIterator __end, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::partition(__begin, __end, __pred); } // Sequential fallback for input iterator case. template inline _FIterator __partition_switch(_FIterator __begin, _FIterator __end, _Predicate __pred, _IteratorTag) { return partition(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template _RAIter __partition_switch(_RAIter __begin, _RAIter __end, _Predicate __pred, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().partition_minimal_n)) { typedef typename std::iterator_traits<_RAIter>:: difference_type _DifferenceType; _DifferenceType __middle = __gnu_parallel:: __parallel_partition(__begin, __end, __pred, __gnu_parallel::__get_max_threads()); return __begin + __middle; } else return partition(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Public interface. template inline _FIterator partition(_FIterator __begin, _FIterator __end, _Predicate __pred) { return __partition_switch(__begin, __end, __pred, std::__iterator_category(__begin)); } // sort interface // Sequential fallback template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::sort(__begin, __end); } // Sequential fallback template inline void sort(_RAIter __begin, _RAIter __end, _Compare __comp, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::sort<_RAIter, _Compare>(__begin, __end, __comp); } // Public interface template void sort(_RAIter __begin, _RAIter __end, _Compare __comp, _Parallelism __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; if (__begin != __end) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().sort_minimal_n)) __gnu_parallel::__parallel_sort( __begin, __end, __comp, __parallelism); else sort(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __gnu_parallel::default_parallel_tag()); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::default_parallel_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::parallel_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::multiway_mergesort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::multiway_mergesort_sampling_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::multiway_mergesort_exact_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::quicksort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::balanced_quicksort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface template void sort(_RAIter __begin, _RAIter __end, _Compare __comp) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, __comp, __gnu_parallel::default_parallel_tag()); } // stable_sort interface // Sequential fallback template inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::stable_sort(__begin, __end); } // Sequential fallback template inline void stable_sort(_RAIter __begin, _RAIter __end, _Compare __comp, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::stable_sort<_RAIter, _Compare>(__begin, __end, __comp); } // Public interface template void stable_sort(_RAIter __begin, _RAIter __end, _Compare __comp, _Parallelism __parallelism) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; if (__begin != __end) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().sort_minimal_n)) __gnu_parallel::__parallel_sort(__begin, __end, __comp, __parallelism); else stable_sort(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } } // Public interface, insert default comparator template inline void stable_sort(_RAIter __begin, _RAIter __end) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __gnu_parallel::default_parallel_tag()); } // Public interface, insert default comparator template inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::default_parallel_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::parallel_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::multiway_mergesort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::quicksort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::balanced_quicksort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface template void stable_sort(_RAIter __begin, _RAIter __end, _Compare __comp) { stable_sort( __begin, __end, __comp, __gnu_parallel::default_parallel_tag()); } // Sequential fallback template inline _OutputIterator merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::merge( __begin1, __end1, __begin2, __end2, __result); } // Sequential fallback template inline _OutputIterator merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Compare __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::merge( __begin1, __end1, __begin2, __end2, __result, __comp); } // Sequential fallback for input iterator case template inline _OutputIterator __merge_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Compare __comp, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::merge(__begin1, __end1, __begin2, __end2, __result, __comp); } // Parallel algorithm for random access iterators template _OutputIterator __merge_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Compare __comp, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( (static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().merge_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().merge_minimal_n))) return __gnu_parallel::__parallel_merge_advance( __begin1, __end1, __begin2, __end2, __result, (__end1 - __begin1) + (__end2 - __begin2), __comp); else return __gnu_parallel::__merge_advance( __begin1, __end1, __begin2, __end2, __result, (__end1 - __begin1) + (__end2 - __begin2), __comp); } // Public interface template inline _OutputIterator merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Compare __comp) { return __merge_switch( __begin1, __end1, __begin2, __end2, __result, __comp, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__result)); } // Public interface, insert default comparator template inline _OutputIterator merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __gnu_parallel::merge(__begin1, __end1, __begin2, __end2, __result, __gnu_parallel::_Less<_ValueType1, _ValueType2>()); } // Sequential fallback template inline void nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end); } // Sequential fallback template inline void nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end, _Compare __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end, __comp); } // Public interface template inline void nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end, _Compare __comp) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().nth_element_minimal_n)) __gnu_parallel::__parallel_nth_element(__begin, __nth, __end, __comp); else nth_element(__begin, __nth, __end, __comp, __gnu_parallel::sequential_tag()); } // Public interface, insert default comparator template inline void nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; __gnu_parallel::nth_element(__begin, __nth, __end, std::less<_ValueType>()); } // Sequential fallback template inline void partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end, _Compare __comp, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end, __comp); } // Sequential fallback template inline void partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end); } // Public interface, parallel algorithm for random access iterators template void partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end, _Compare __comp) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().partial_sort_minimal_n)) __gnu_parallel:: __parallel_partial_sort(__begin, __middle, __end, __comp); else partial_sort(__begin, __middle, __end, __comp, __gnu_parallel::sequential_tag()); } // Public interface, insert default comparator template inline void partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; __gnu_parallel::partial_sort(__begin, __middle, __end, std::less<_ValueType>()); } // Sequential fallback template inline _FIterator max_element(_FIterator __begin, _FIterator __end, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::max_element(__begin, __end); } // Sequential fallback template inline _FIterator max_element(_FIterator __begin, _FIterator __end, _Compare __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::max_element(__begin, __end, __comp); } // Sequential fallback for input iterator case template inline _FIterator __max_element_switch(_FIterator __begin, _FIterator __end, _Compare __comp, _IteratorTag) { return max_element(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template _RAIter __max_element_switch(_RAIter __begin, _RAIter __end, _Compare __comp, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().max_element_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { _RAIter __res(__begin); __gnu_parallel::__identity_selector<_RAIter> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __gnu_parallel::_Nothing(), __functionality, __gnu_parallel::__max_element_reduct<_Compare, _RAIter>(__comp), __res, __res, -1, __parallelism_tag); return __res; } else return max_element(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } // Public interface, insert default comparator template inline _FIterator max_element(_FIterator __begin, _FIterator __end, __gnu_parallel::_Parallelism __parallelism_tag) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return max_element(__begin, __end, std::less<_ValueType>(), __parallelism_tag); } template inline _FIterator max_element(_FIterator __begin, _FIterator __end) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return __gnu_parallel::max_element(__begin, __end, std::less<_ValueType>()); } // Public interface template inline _FIterator max_element(_FIterator __begin, _FIterator __end, _Compare __comp, __gnu_parallel::_Parallelism __parallelism_tag) { return __max_element_switch(__begin, __end, __comp, std::__iterator_category(__begin), __parallelism_tag); } template inline _FIterator max_element(_FIterator __begin, _FIterator __end, _Compare __comp) { return __max_element_switch(__begin, __end, __comp, std::__iterator_category(__begin)); } // Sequential fallback template inline _FIterator min_element(_FIterator __begin, _FIterator __end, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::min_element(__begin, __end); } // Sequential fallback template inline _FIterator min_element(_FIterator __begin, _FIterator __end, _Compare __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::min_element(__begin, __end, __comp); } // Sequential fallback for input iterator case template inline _FIterator __min_element_switch(_FIterator __begin, _FIterator __end, _Compare __comp, _IteratorTag) { return min_element(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template _RAIter __min_element_switch(_RAIter __begin, _RAIter __end, _Compare __comp, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().min_element_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { _RAIter __res(__begin); __gnu_parallel::__identity_selector<_RAIter> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __gnu_parallel::_Nothing(), __functionality, __gnu_parallel::__min_element_reduct<_Compare, _RAIter>(__comp), __res, __res, -1, __parallelism_tag); return __res; } else return min_element(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } // Public interface, insert default comparator template inline _FIterator min_element(_FIterator __begin, _FIterator __end, __gnu_parallel::_Parallelism __parallelism_tag) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return min_element(__begin, __end, std::less<_ValueType>(), __parallelism_tag); } template inline _FIterator min_element(_FIterator __begin, _FIterator __end) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return __gnu_parallel::min_element(__begin, __end, std::less<_ValueType>()); } // Public interface template inline _FIterator min_element(_FIterator __begin, _FIterator __end, _Compare __comp, __gnu_parallel::_Parallelism __parallelism_tag) { return __min_element_switch(__begin, __end, __comp, std::__iterator_category(__begin), __parallelism_tag); } template inline _FIterator min_element(_FIterator __begin, _FIterator __end, _Compare __comp) { return __min_element_switch(__begin, __end, __comp, std::__iterator_category(__begin)); } } // end namespace } // end namespace #endif /* _GLIBCXX_PARALLEL_ALGO_H */ 8/parallel/merge.h000064400000022552152526447520010001 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/merge.h * @brief Parallel implementation of std::merge(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_MERGE_H #define _GLIBCXX_PARALLEL_MERGE_H 1 #include #include namespace __gnu_parallel { /** @brief Merge routine being able to merge only the @c __max_length * smallest elements. * * The @c __begin iterators are advanced accordingly, they might not * reach @c __end, in contrast to the usual variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template _OutputIterator __merge_advance_usual(_RAIter1& __begin1, _RAIter1 __end1, _RAIter2& __begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp) { typedef _DifferenceTp _DifferenceType; while (__begin1 != __end1 && __begin2 != __end2 && __max_length > 0) { // array1[__i1] < array0[i0] if (__comp(*__begin2, *__begin1)) *__target++ = *__begin2++; else *__target++ = *__begin1++; --__max_length; } if (__begin1 != __end1) { __target = std::copy(__begin1, __begin1 + __max_length, __target); __begin1 += __max_length; } else { __target = std::copy(__begin2, __begin2 + __max_length, __target); __begin2 += __max_length; } return __target; } /** @brief Merge routine being able to merge only the @c __max_length * smallest elements. * * The @c __begin iterators are advanced accordingly, they might not * reach @c __end, in contrast to the usual variant. * Specially designed code should allow the compiler to generate * conditional moves instead of branches. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template _OutputIterator __merge_advance_movc(_RAIter1& __begin1, _RAIter1 __end1, _RAIter2& __begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp) { typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_RAIter2>::value_type _ValueType2; #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__max_length >= 0); #endif while (__begin1 != __end1 && __begin2 != __end2 && __max_length > 0) { _RAIter1 __next1 = __begin1 + 1; _RAIter2 __next2 = __begin2 + 1; _ValueType1 __element1 = *__begin1; _ValueType2 __element2 = *__begin2; if (__comp(__element2, __element1)) { __element1 = __element2; __begin2 = __next2; } else __begin1 = __next1; *__target = __element1; ++__target; --__max_length; } if (__begin1 != __end1) { __target = std::copy(__begin1, __begin1 + __max_length, __target); __begin1 += __max_length; } else { __target = std::copy(__begin2, __begin2 + __max_length, __target); __begin2 += __max_length; } return __target; } /** @brief Merge routine being able to merge only the @c __max_length * smallest elements. * * The @c __begin iterators are advanced accordingly, they might not * reach @c __end, in contrast to the usual variant. * Static switch on whether to use the conditional-move variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template inline _OutputIterator __merge_advance(_RAIter1& __begin1, _RAIter1 __end1, _RAIter2& __begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp) { _GLIBCXX_CALL(__max_length) return __merge_advance_movc(__begin1, __end1, __begin2, __end2, __target, __max_length, __comp); } /** @brief Merge routine fallback to sequential in case the iterators of the two input sequences are of different type. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template inline _RAIter3 __parallel_merge_advance(_RAIter1& __begin1, _RAIter1 __end1, _RAIter2& __begin2, // different iterators, parallel implementation // not available _RAIter2 __end2, _RAIter3 __target, typename std::iterator_traits<_RAIter1>:: difference_type __max_length, _Compare __comp) { return __merge_advance(__begin1, __end1, __begin2, __end2, __target, __max_length, __comp); } /** @brief Parallel merge routine being able to merge only the @c * __max_length smallest elements. * * The @c __begin iterators are advanced accordingly, they might not * reach @c __end, in contrast to the usual variant. * The functionality is projected onto parallel_multiway_merge. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template inline _RAIter3 __parallel_merge_advance(_RAIter1& __begin1, _RAIter1 __end1, _RAIter1& __begin2, _RAIter1 __end2, _RAIter3 __target, typename std::iterator_traits<_RAIter1>:: difference_type __max_length, _Compare __comp) { typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; typedef typename std::iterator_traits<_RAIter1>:: difference_type _DifferenceType1 /* == difference_type2 */; typedef typename std::iterator_traits<_RAIter3>:: difference_type _DifferenceType3; typedef typename std::pair<_RAIter1, _RAIter1> _IteratorPair; _IteratorPair __seqs[2] = { std::make_pair(__begin1, __end1), std::make_pair(__begin2, __end2) }; _RAIter3 __target_end = parallel_multiway_merge < /* __stable = */ true, /* __sentinels = */ false> (__seqs, __seqs + 2, __target, multiway_merge_exact_splitting < /* __stable = */ true, _IteratorPair*, _Compare, _DifferenceType1>, __max_length, __comp, omp_get_max_threads()); return __target_end; } } //namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_MERGE_H */ 8/parallel/numeric000064400000050355152526447520010120 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** * @file parallel/numeric * * @brief Parallel STL function calls corresponding to stl_numeric.h. * The functions defined here mainly do case switches and * call the actual parallelized versions in other files. * Inlining policy: Functions that basically only contain one function call, * are declared inline. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_NUMERIC_H #define _GLIBCXX_PARALLEL_NUMERIC_H 1 #include #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { // Sequential fallback. template inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::accumulate(__begin, __end, __init); } template inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::accumulate(__begin, __end, __init, __binary_op); } // Sequential fallback for input iterator case. template inline _Tp __accumulate_switch(_IIter __begin, _IIter __end, _Tp __init, _IteratorTag) { return accumulate(__begin, __end, __init, __gnu_parallel::sequential_tag()); } template inline _Tp __accumulate_switch(_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op, _IteratorTag) { return accumulate(__begin, __end, __init, __binary_op, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template _Tp __accumulate_switch(__RAIter __begin, __RAIter __end, _Tp __init, _BinaryOperation __binary_op, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().accumulate_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { _Tp __res = __init; __gnu_parallel::__accumulate_selector<__RAIter> __my_selector; __gnu_parallel:: __for_each_template_random_access_ed(__begin, __end, __gnu_parallel::_Nothing(), __my_selector, __gnu_parallel:: __accumulate_binop_reduct <_BinaryOperation>(__binary_op), __res, __res, -1); return __res; } else return accumulate(__begin, __end, __init, __binary_op, __gnu_parallel::sequential_tag()); } // Public interface. template inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, __gnu_parallel::_Parallelism __parallelism_tag) { typedef std::iterator_traits<_IIter> _IteratorTraits; typedef typename _IteratorTraits::value_type _ValueType; typedef typename _IteratorTraits::iterator_category _IteratorCategory; return __accumulate_switch(__begin, __end, __init, __gnu_parallel::_Plus<_Tp, _ValueType>(), _IteratorCategory(), __parallelism_tag); } template inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init) { typedef std::iterator_traits<_IIter> _IteratorTraits; typedef typename _IteratorTraits::value_type _ValueType; typedef typename _IteratorTraits::iterator_category _IteratorCategory; return __accumulate_switch(__begin, __end, __init, __gnu_parallel::_Plus<_Tp, _ValueType>(), _IteratorCategory()); } template inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter> _IteratorTraits; typedef typename _IteratorTraits::iterator_category _IteratorCategory; return __accumulate_switch(__begin, __end, __init, __binary_op, _IteratorCategory(), __parallelism_tag); } template inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op) { typedef iterator_traits<_IIter> _IteratorTraits; typedef typename _IteratorTraits::iterator_category _IteratorCategory; return __accumulate_switch(__begin, __end, __init, __binary_op, _IteratorCategory()); } // Sequential fallback. template inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::inner_product( __first1, __last1, __first2, __init); } template inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::inner_product(__first1, __last1, __first2, __init, __binary_op1, __binary_op2); } // Parallel algorithm for random access iterators. template _Tp __inner_product_switch(_RAIter1 __first1, _RAIter1 __last1, _RAIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION((__last1 - __first1) >= __gnu_parallel::_Settings::get(). accumulate_minimal_n && __gnu_parallel:: __is_parallel(__parallelism_tag))) { _Tp __res = __init; __gnu_parallel:: __inner_product_selector<_RAIter1, _RAIter2, _Tp> __my_selector(__first1, __first2); __gnu_parallel:: __for_each_template_random_access_ed( __first1, __last1, __binary_op2, __my_selector, __binary_op1, __res, __res, -1); return __res; } else return inner_product(__first1, __last1, __first2, __init, __gnu_parallel::sequential_tag()); } // No parallelism for input iterators. template inline _Tp __inner_product_switch(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2, _IteratorTag1, _IteratorTag2) { return inner_product(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, __gnu_parallel::sequential_tag()); } template inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::iterator_category _IteratorCategory2; return __inner_product_switch(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, _IteratorCategory1(), _IteratorCategory2(), __parallelism_tag); } template inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::iterator_category _IteratorCategory2; return __inner_product_switch(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, _IteratorCategory1(), _IteratorCategory2()); } template inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::value_type _ValueType1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::value_type _ValueType2; typedef typename __gnu_parallel::_Multiplies<_ValueType1, _ValueType2>::result_type _MultipliesResultType; return __gnu_parallel::inner_product(__first1, __last1, __first2, __init, __gnu_parallel::_Plus<_Tp, _MultipliesResultType>(), __gnu_parallel:: _Multiplies<_ValueType1, _ValueType2>(), __parallelism_tag); } template inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::value_type _ValueType1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::value_type _ValueType2; typedef typename __gnu_parallel::_Multiplies<_ValueType1, _ValueType2>::result_type _MultipliesResultType; return __gnu_parallel::inner_product(__first1, __last1, __first2, __init, __gnu_parallel::_Plus<_Tp, _MultipliesResultType>(), __gnu_parallel:: _Multiplies<_ValueType1, _ValueType2>()); } // Sequential fallback. template inline _OutputIterator partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::partial_sum(__begin, __end, __result); } // Sequential fallback. template inline _OutputIterator partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::partial_sum(__begin, __end, __result, __bin_op); } // Sequential fallback for input iterator case. template inline _OutputIterator __partial_sum_switch(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::partial_sum(__begin, __end, __result, __bin_op); } // Parallel algorithm for random access iterators. template _OutputIterator __partial_sum_switch(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().partial_sum_minimal_n)) return __gnu_parallel::__parallel_partial_sum(__begin, __end, __result, __bin_op); else return partial_sum(__begin, __end, __result, __bin_op, __gnu_parallel::sequential_tag()); } // Public interface. template inline _OutputIterator partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result) { typedef typename iterator_traits<_IIter>::value_type _ValueType; return __gnu_parallel::partial_sum(__begin, __end, __result, std::plus<_ValueType>()); } // Public interface template inline _OutputIterator partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __binary_op) { typedef iterator_traits<_IIter> _ITraitsType; typedef typename _ITraitsType::iterator_category _IIteratorCategory; typedef iterator_traits<_OutputIterator> _OTraitsType; typedef typename _OTraitsType::iterator_category _OIterCategory; return __partial_sum_switch(__begin, __end, __result, __binary_op, _IIteratorCategory(), _OIterCategory()); } // Sequential fallback. template inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::adjacent_difference(__begin, __end, __result); } // Sequential fallback. template inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::adjacent_difference(__begin, __end, __result, __bin_op); } // Sequential fallback for input iterator case. template inline _OutputIterator __adjacent_difference_switch(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, _IteratorTag1, _IteratorTag2) { return adjacent_difference(__begin, __end, __result, __bin_op, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template _OutputIterator __adjacent_difference_switch(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().adjacent_difference_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy = true; typedef __gnu_parallel::_IteratorPair<_IIter, _OutputIterator, random_access_iterator_tag> _ItTrip; *__result = *__begin; _ItTrip __begin_pair(__begin + 1, __result + 1), __end_pair(__end, __result + (__end - __begin)); __gnu_parallel::__adjacent_difference_selector<_ItTrip> __functionality; __gnu_parallel:: __for_each_template_random_access_ed( __begin_pair, __end_pair, __bin_op, __functionality, __gnu_parallel::_DummyReduct(), __dummy, __dummy, -1); return __functionality._M_finish_iterator; } else return adjacent_difference(__begin, __end, __result, __bin_op, __gnu_parallel::sequential_tag()); } // Public interface. template inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; return adjacent_difference(__begin, __end, __result, std::minus<_ValueType>(), __parallelism_tag); } template inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result) { typedef iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; return adjacent_difference(__begin, __end, __result, std::minus<_ValueType>()); } template inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __binary_op, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter> _ITraitsType; typedef typename _ITraitsType::iterator_category _IIteratorCategory; typedef iterator_traits<_OutputIterator> _OTraitsType; typedef typename _OTraitsType::iterator_category _OIterCategory; return __adjacent_difference_switch(__begin, __end, __result, __binary_op, _IIteratorCategory(), _OIterCategory(), __parallelism_tag); } template inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __binary_op) { typedef iterator_traits<_IIter> _ITraitsType; typedef typename _ITraitsType::iterator_category _IIteratorCategory; typedef iterator_traits<_OutputIterator> _OTraitsType; typedef typename _OTraitsType::iterator_category _OIterCategory; return __adjacent_difference_switch(__begin, __end, __result, __binary_op, _IIteratorCategory(), _OIterCategory()); } } // end namespace } // end namespace #endif /* _GLIBCXX_NUMERIC_H */ 8/parallel/base.h000064400000030125152526447520007607 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/base.h * @brief Sequential helper functions. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_BASE_H #define _GLIBCXX_PARALLEL_BASE_H 1 #include #include #include #include #include #include // Parallel mode namespaces. /** * @namespace std::__parallel * @brief GNU parallel code, replaces standard behavior with parallel behavior. */ namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { } } /** * @namespace __gnu_parallel * @brief GNU parallel code for public use. */ namespace __gnu_parallel { // Import all the parallel versions of components in namespace std. using namespace std::__parallel; } /** * @namespace __gnu_sequential * @brief GNU sequential classes for public use. */ namespace __gnu_sequential { // Import whatever is the serial version. #ifdef _GLIBCXX_PARALLEL using namespace std::_GLIBCXX_STD_A; #else using namespace std; #endif } namespace __gnu_parallel { // NB: Including this file cannot produce (unresolved) symbols from // the OpenMP runtime unless the parallel mode is actually invoked // and active, which imples that the OpenMP runtime is actually // going to be linked in. inline _ThreadIndex __get_max_threads() { _ThreadIndex __i = omp_get_max_threads(); return __i > 1 ? __i : 1; } inline bool __is_parallel(const _Parallelism __p) { return __p != sequential; } /** @brief Calculates the rounded-down logarithm of @c __n for base 2. * @param __n Argument. * @return Returns 0 for any argument <1. */ template inline _Size __rd_log2(_Size __n) { _Size __k; for (__k = 0; __n > 1; __n >>= 1) ++__k; return __k; } /** @brief Encode two integers into one gnu_parallel::_CASable. * @param __a First integer, to be encoded in the most-significant @c * _CASable_bits/2 bits. * @param __b Second integer, to be encoded in the least-significant * @c _CASable_bits/2 bits. * @return value encoding @c __a and @c __b. * @see __decode2 */ inline _CASable __encode2(int __a, int __b) //must all be non-negative, actually { return (((_CASable)__a) << (_CASable_bits / 2)) | (((_CASable)__b) << 0); } /** @brief Decode two integers from one gnu_parallel::_CASable. * @param __x __gnu_parallel::_CASable to decode integers from. * @param __a First integer, to be decoded from the most-significant * @c _CASable_bits/2 bits of @c __x. * @param __b Second integer, to be encoded in the least-significant * @c _CASable_bits/2 bits of @c __x. * @see __encode2 */ inline void __decode2(_CASable __x, int& __a, int& __b) { __a = (int)((__x >> (_CASable_bits / 2)) & _CASable_mask); __b = (int)((__x >> 0 ) & _CASable_mask); } //needed for parallel "numeric", even if "algorithm" not included /** @brief Equivalent to std::min. */ template inline const _Tp& min(const _Tp& __a, const _Tp& __b) { return (__a < __b) ? __a : __b; } /** @brief Equivalent to std::max. */ template inline const _Tp& max(const _Tp& __a, const _Tp& __b) { return (__a > __b) ? __a : __b; } /** @brief Constructs predicate for equality from strict weak * ordering predicate */ template class _EqualFromLess : public std::binary_function<_T1, _T2, bool> { private: _Compare& _M_comp; public: _EqualFromLess(_Compare& __comp) : _M_comp(__comp) { } bool operator()(const _T1& __a, const _T2& __b) { return !_M_comp(__a, __b) && !_M_comp(__b, __a); } }; /** @brief Similar to std::unary_negate, * but giving the argument types explicitly. */ template class __unary_negate : public std::unary_function { protected: _Predicate _M_pred; public: explicit __unary_negate(const _Predicate& __x) : _M_pred(__x) { } bool operator()(const argument_type& __x) { return !_M_pred(__x); } }; /** @brief Similar to std::binder1st, * but giving the argument types explicitly. */ template class __binder1st : public std::unary_function<_SecondArgumentType, _ResultType> { protected: _Operation _M_op; _FirstArgumentType _M_value; public: __binder1st(const _Operation& __x, const _FirstArgumentType& __y) : _M_op(__x), _M_value(__y) { } _ResultType operator()(const _SecondArgumentType& __x) { return _M_op(_M_value, __x); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 109. Missing binders for non-const sequence elements _ResultType operator()(_SecondArgumentType& __x) const { return _M_op(_M_value, __x); } }; /** * @brief Similar to std::binder2nd, but giving the argument types * explicitly. */ template class __binder2nd : public std::unary_function<_FirstArgumentType, _ResultType> { protected: _Operation _M_op; _SecondArgumentType _M_value; public: __binder2nd(const _Operation& __x, const _SecondArgumentType& __y) : _M_op(__x), _M_value(__y) { } _ResultType operator()(const _FirstArgumentType& __x) const { return _M_op(__x, _M_value); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 109. Missing binders for non-const sequence elements _ResultType operator()(_FirstArgumentType& __x) { return _M_op(__x, _M_value); } }; /** @brief Similar to std::equal_to, but allows two different types. */ template struct _EqualTo : std::binary_function<_T1, _T2, bool> { bool operator()(const _T1& __t1, const _T2& __t2) const { return __t1 == __t2; } }; /** @brief Similar to std::less, but allows two different types. */ template struct _Less : std::binary_function<_T1, _T2, bool> { bool operator()(const _T1& __t1, const _T2& __t2) const { return __t1 < __t2; } bool operator()(const _T2& __t2, const _T1& __t1) const { return __t2 < __t1; } }; // Partial specialization for one type. Same as std::less. template struct _Less<_Tp, _Tp> : public std::less<_Tp> { }; /** @brief Similar to std::plus, but allows two different types. */ template(0) + *static_cast<_Tp2*>(0))> struct _Plus : public std::binary_function<_Tp1, _Tp2, _Result> { _Result operator()(const _Tp1& __x, const _Tp2& __y) const { return __x + __y; } }; // Partial specialization for one type. Same as std::plus. template struct _Plus<_Tp, _Tp, _Tp> : public std::plus<_Tp> { }; /** @brief Similar to std::multiplies, but allows two different types. */ template(0) * *static_cast<_Tp2*>(0))> struct _Multiplies : public std::binary_function<_Tp1, _Tp2, _Result> { _Result operator()(const _Tp1& __x, const _Tp2& __y) const { return __x * __y; } }; // Partial specialization for one type. Same as std::multiplies. template struct _Multiplies<_Tp, _Tp, _Tp> : public std::multiplies<_Tp> { }; /** @brief _Iterator associated with __gnu_parallel::_PseudoSequence. * If features the usual random-access iterator functionality. * @param _Tp Sequence _M_value type. * @param _DifferenceTp Sequence difference type. */ template class _PseudoSequenceIterator { public: typedef _DifferenceTp _DifferenceType; _PseudoSequenceIterator(const _Tp& __val, _DifferenceType __pos) : _M_val(__val), _M_pos(__pos) { } // Pre-increment operator. _PseudoSequenceIterator& operator++() { ++_M_pos; return *this; } // Post-increment operator. _PseudoSequenceIterator operator++(int) { return _PseudoSequenceIterator(_M_pos++); } const _Tp& operator*() const { return _M_val; } const _Tp& operator[](_DifferenceType) const { return _M_val; } bool operator==(const _PseudoSequenceIterator& __i2) { return _M_pos == __i2._M_pos; } bool operator!=(const _PseudoSequenceIterator& __i2) { return _M_pos != __i2._M_pos; } _DifferenceType operator-(const _PseudoSequenceIterator& __i2) { return _M_pos - __i2._M_pos; } private: const _Tp& _M_val; _DifferenceType _M_pos; }; /** @brief Sequence that conceptually consists of multiple copies of the same element. * The copies are not stored explicitly, of course. * @param _Tp Sequence _M_value type. * @param _DifferenceTp Sequence difference type. */ template class _PseudoSequence { public: typedef _DifferenceTp _DifferenceType; // Better cast down to uint64_t, than up to _DifferenceTp. typedef _PseudoSequenceIterator<_Tp, uint64_t> iterator; /** @brief Constructor. * @param __val Element of the sequence. * @param __count Number of (virtual) copies. */ _PseudoSequence(const _Tp& __val, _DifferenceType __count) : _M_val(__val), _M_count(__count) { } /** @brief Begin iterator. */ iterator begin() const { return iterator(_M_val, 0); } /** @brief End iterator. */ iterator end() const { return iterator(_M_val, _M_count); } private: const _Tp& _M_val; _DifferenceType _M_count; }; /** @brief Compute the median of three referenced elements, according to @c __comp. * @param __a First iterator. * @param __b Second iterator. * @param __c Third iterator. * @param __comp Comparator. */ template _RAIter __median_of_three_iterators(_RAIter __a, _RAIter __b, _RAIter __c, _Compare __comp) { if (__comp(*__a, *__b)) if (__comp(*__b, *__c)) return __b; else if (__comp(*__a, *__c)) return __c; else return __a; else { // Just swap __a and __b. if (__comp(*__a, *__c)) return __a; else if (__comp(*__b, *__c)) return __c; else return __b; } } #if _GLIBCXX_PARALLEL_ASSERTIONS && defined(__glibcxx_assert_impl) #define _GLIBCXX_PARALLEL_ASSERT(_Condition) __glibcxx_assert_impl(_Condition) #else #define _GLIBCXX_PARALLEL_ASSERT(_Condition) #endif } //namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_BASE_H */ 8/parallel/basic_iterator.h000064400000003062152526447520011667 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/basic_iterator.h * @brief Includes the original header files concerned with iterators * except for stream iterators. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_BASIC_ITERATOR_H #define _GLIBCXX_PARALLEL_BASIC_ITERATOR_H 1 #include #include #include #include #endif /* _GLIBCXX_PARALLEL_BASIC_ITERATOR_H */ 8/parallel/omp_loop.h000064400000007677152526447520010541 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/omp_loop.h * @brief Parallelization of embarrassingly parallel execution by * means of an OpenMP for loop. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_OMP_LOOP_H #define _GLIBCXX_PARALLEL_OMP_LOOP_H 1 #include #include #include #include namespace __gnu_parallel { /** @brief Embarrassingly parallel algorithm for random access * iterators, using an OpenMP for loop. * * @param __begin Begin iterator of element sequence. * @param __end End iterator of element sequence. * @param __o User-supplied functor (comparator, predicate, adding * functor, etc.). * @param __f Functor to @a process an element with __op (depends on * desired functionality, e. g. for std::for_each(), ...). * @param __r Functor to @a add a single __result to the already * processed elements (depends on functionality). * @param __base Base value for reduction. * @param __output Pointer to position where final result is written to * @param __bound Maximum number of elements processed (e. g. for * std::count_n()). * @return User-supplied functor (that may contain a part of the result). */ template _Op __for_each_template_random_access_omp_loop(_RAIter __begin, _RAIter __end, _Op __o, _Fu& __f, _Red __r, _Result __base, _Result& __output, typename std::iterator_traits<_RAIter>::difference_type __bound) { typedef typename std::iterator_traits<_RAIter>::difference_type _DifferenceType; _DifferenceType __length = __end - __begin; _ThreadIndex __num_threads = __gnu_parallel::min<_DifferenceType> (__get_max_threads(), __length); _Result *__thread_results; # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __thread_results = new _Result[__num_threads]; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __thread_results[__i] = _Result(); } _ThreadIndex __iam = omp_get_thread_num(); #pragma omp for schedule(dynamic, _Settings::get().workstealing_chunk_size) for (_DifferenceType __pos = 0; __pos < __length; ++__pos) __thread_results[__iam] = __r(__thread_results[__iam], __f(__o, __begin+__pos)); } //parallel for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __output = __r(__output, __thread_results[__i]); delete [] __thread_results; // Points to last element processed (needed as return value for // some algorithms like transform). __f._M_finish_iterator = __begin + __length; return __o; } } // end namespace #endif /* _GLIBCXX_PARALLEL_OMP_LOOP_H */ 8/parallel/types.h000064400000007204152526447520010043 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/types.h * @brief Basic types and typedefs. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_TYPES_H #define _GLIBCXX_PARALLEL_TYPES_H 1 #include #include #include namespace __gnu_parallel { // Enumerated types. /// Run-time equivalents for the compile-time tags. enum _Parallelism { /// Not parallel. sequential, /// Parallel unbalanced (equal-sized chunks). parallel_unbalanced, /// Parallel balanced (work-stealing). parallel_balanced, /// Parallel with OpenMP dynamic load-balancing. parallel_omp_loop, /// Parallel with OpenMP static load-balancing. parallel_omp_loop_static, /// Parallel with OpenMP taskqueue construct. parallel_taskqueue }; /// Strategies for run-time algorithm selection: // force_sequential, force_parallel, heuristic. enum _AlgorithmStrategy { heuristic, force_sequential, force_parallel }; /// Sorting algorithms: // multi-way mergesort, quicksort, load-balanced quicksort. enum _SortAlgorithm { MWMS, QS, QS_BALANCED }; /// Merging algorithms: // bubblesort-alike, loser-tree variants, enum __sentinel. enum _MultiwayMergeAlgorithm { LOSER_TREE }; /// Partial sum algorithms: recursive, linear. enum _PartialSumAlgorithm { RECURSIVE, LINEAR }; /// Sorting/merging algorithms: sampling, __exact. enum _SplittingAlgorithm { SAMPLING, EXACT }; /// Find algorithms: // growing blocks, equal-sized blocks, equal splitting. enum _FindAlgorithm { GROWING_BLOCKS, CONSTANT_SIZE_BLOCKS, EQUAL_SPLIT }; /** * @brief Unsigned integer to index __elements. * The total number of elements for each algorithm must fit into this type. */ typedef uint64_t _SequenceIndex; /** * @brief Unsigned integer to index a thread number. * The maximum thread number (for each processor) must fit into this type. */ typedef uint16_t _ThreadIndex; // XXX atomics interface? /// Longest compare-and-swappable integer type on this platform. typedef int64_t _CASable; /// Number of bits of _CASable. static const int _CASable_bits = std::numeric_limits<_CASable>::digits; /// ::_CASable with the right half of bits set to 1. static const _CASable _CASable_mask = ((_CASable(1) << (_CASable_bits / 2)) - 1); } #endif /* _GLIBCXX_PARALLEL_TYPES_H */ 8/parallel/workstealing.h000064400000022614152526447520011412 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/workstealing.h * @brief Parallelization of embarrassingly parallel execution by * means of work-stealing. * * Work stealing is described in * * R. D. Blumofe and C. E. Leiserson. * Scheduling multithreaded computations by work stealing. * Journal of the ACM, 46(5):720–748, 1999. * * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_WORKSTEALING_H #define _GLIBCXX_PARALLEL_WORKSTEALING_H 1 #include #include #include namespace __gnu_parallel { #define _GLIBCXX_JOB_VOLATILE volatile /** @brief One __job for a certain thread. */ template struct _Job { typedef _DifferenceTp _DifferenceType; /** @brief First element. * * Changed by owning and stealing thread. By stealing thread, * always incremented. */ _GLIBCXX_JOB_VOLATILE _DifferenceType _M_first; /** @brief Last element. * * Changed by owning thread only. */ _GLIBCXX_JOB_VOLATILE _DifferenceType _M_last; /** @brief Number of elements, i.e. @c _M_last-_M_first+1. * * Changed by owning thread only. */ _GLIBCXX_JOB_VOLATILE _DifferenceType _M_load; }; /** @brief Work stealing algorithm for random access iterators. * * Uses O(1) additional memory. Synchronization at job lists is * done with atomic operations. * @param __begin Begin iterator of element sequence. * @param __end End iterator of element sequence. * @param __op User-supplied functor (comparator, predicate, adding * functor, ...). * @param __f Functor to @a process an element with __op (depends on * desired functionality, e. g. for std::for_each(), ...). * @param __r Functor to @a add a single __result to the already * processed elements (depends on functionality). * @param __base Base value for reduction. * @param __output Pointer to position where final result is written to * @param __bound Maximum number of elements processed (e. g. for * std::count_n()). * @return User-supplied functor (that may contain a part of the result). */ template _Op __for_each_template_random_access_workstealing(_RAIter __begin, _RAIter __end, _Op __op, _Fu& __f, _Red __r, _Result __base, _Result& __output, typename std::iterator_traits<_RAIter>::difference_type __bound) { _GLIBCXX_CALL(__end - __begin) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; const _Settings& __s = _Settings::get(); _DifferenceType __chunk_size = static_cast<_DifferenceType>(__s.workstealing_chunk_size); // How many jobs? _DifferenceType __length = (__bound < 0) ? (__end - __begin) : __bound; // To avoid false sharing in a cache line. const int __stride = (__s.cache_line_size * 10 / sizeof(_Job<_DifferenceType>) + 1); // Total number of threads currently working. _ThreadIndex __busy = 0; _Job<_DifferenceType> *__job; omp_lock_t __output_lock; omp_init_lock(&__output_lock); // Write base value to output. __output = __base; // No more threads than jobs, at least one thread. _ThreadIndex __num_threads = __gnu_parallel::max<_ThreadIndex> (1, __gnu_parallel::min<_DifferenceType>(__length, __get_max_threads())); # pragma omp parallel shared(__busy) num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); // Create job description array. __job = new _Job<_DifferenceType>[__num_threads * __stride]; } // Initialization phase. // Flags for every thread if it is doing productive work. bool __iam_working = false; // Thread id. _ThreadIndex __iam = omp_get_thread_num(); // This job. _Job<_DifferenceType>& __my_job = __job[__iam * __stride]; // Random number (for work stealing). _ThreadIndex __victim; // Local value for reduction. _Result __result = _Result(); // Number of elements to steal in one attempt. _DifferenceType __steal; // Every thread has its own random number generator // (modulo __num_threads). _RandomNumber __rand_gen(__iam, __num_threads); // This thread is currently working. # pragma omp atomic ++__busy; __iam_working = true; // How many jobs per thread? last thread gets the rest. __my_job._M_first = static_cast<_DifferenceType> (__iam * (__length / __num_threads)); __my_job._M_last = (__iam == (__num_threads - 1) ? (__length - 1) : ((__iam + 1) * (__length / __num_threads) - 1)); __my_job._M_load = __my_job._M_last - __my_job._M_first + 1; // Init result with _M_first value (to have a base value for reduction) if (__my_job._M_first <= __my_job._M_last) { // Cannot use volatile variable directly. _DifferenceType __my_first = __my_job._M_first; __result = __f(__op, __begin + __my_first); ++__my_job._M_first; --__my_job._M_load; } _RAIter __current; # pragma omp barrier // Actual work phase // Work on own or stolen current start while (__busy > 0) { // Work until no productive thread left. # pragma omp flush(__busy) // Thread has own work to do while (__my_job._M_first <= __my_job._M_last) { // fetch-and-add call // Reserve current job block (size __chunk_size) in my queue. _DifferenceType __current_job = __fetch_and_add<_DifferenceType>(&(__my_job._M_first), __chunk_size); // Update _M_load, to make the three values consistent, // _M_first might have been changed in the meantime __my_job._M_load = __my_job._M_last - __my_job._M_first + 1; for (_DifferenceType __job_counter = 0; __job_counter < __chunk_size && __current_job <= __my_job._M_last; ++__job_counter) { // Yes: process it! __current = __begin + __current_job; ++__current_job; // Do actual work. __result = __r(__result, __f(__op, __current)); } # pragma omp flush(__busy) } // After reaching this point, a thread's __job list is empty. if (__iam_working) { // This thread no longer has work. # pragma omp atomic --__busy; __iam_working = false; } _DifferenceType __supposed_first, __supposed_last, __supposed_load; do { // Find random nonempty deque (not own), do consistency check. __yield(); # pragma omp flush(__busy) __victim = __rand_gen(); __supposed_first = __job[__victim * __stride]._M_first; __supposed_last = __job[__victim * __stride]._M_last; __supposed_load = __job[__victim * __stride]._M_load; } while (__busy > 0 && ((__supposed_load <= 0) || ((__supposed_first + __supposed_load - 1) != __supposed_last))); if (__busy == 0) break; if (__supposed_load > 0) { // Has work and work to do. // Number of elements to steal (at least one). __steal = (__supposed_load < 2) ? 1 : __supposed_load / 2; // Push __victim's current start forward. _DifferenceType __stolen_first = __fetch_and_add<_DifferenceType> (&(__job[__victim * __stride]._M_first), __steal); _DifferenceType __stolen_try = (__stolen_first + __steal - _DifferenceType(1)); __my_job._M_first = __stolen_first; __my_job._M_last = __gnu_parallel::min(__stolen_try, __supposed_last); __my_job._M_load = __my_job._M_last - __my_job._M_first + 1; // Has potential work again. # pragma omp atomic ++__busy; __iam_working = true; # pragma omp flush(__busy) } # pragma omp flush(__busy) } // end while __busy > 0 // Add accumulated result to output. omp_set_lock(&__output_lock); __output = __r(__output, __result); omp_unset_lock(&__output_lock); } delete[] __job; // Points to last element processed (needed as return value for // some algorithms like transform) __f._M_finish_iterator = __begin + __length; omp_destroy_lock(&__output_lock); return __op; } } // end namespace #endif /* _GLIBCXX_PARALLEL_WORKSTEALING_H */ 8/parallel/compiletime_settings.h000064400000005467152526447520013137 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/compiletime_settings.h * @brief Defines on options concerning debugging and performance, at * compile-time. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #include /** @brief Determine verbosity level of the parallel mode. * Level 1 prints a message each time a parallel-mode function is entered. */ #define _GLIBCXX_VERBOSE_LEVEL 0 /** @def _GLIBCXX_CALL * @brief Macro to produce log message when entering a function. * @param __n Input size. * @see _GLIBCXX_VERBOSE_LEVEL */ #if (_GLIBCXX_VERBOSE_LEVEL == 0) #define _GLIBCXX_CALL(__n) #endif #if (_GLIBCXX_VERBOSE_LEVEL == 1) #define _GLIBCXX_CALL(__n) \ printf(" %__s:\niam = %d, __n = %ld, __num_threads = %d\n", \ __PRETTY_FUNCTION__, omp_get_thread_num(), (__n), __get_max_threads()); #endif #ifndef _GLIBCXX_SCALE_DOWN_FPU /** @brief Use floating-point scaling instead of modulo for mapping * random numbers to a range. This can be faster on certain CPUs. */ #define _GLIBCXX_SCALE_DOWN_FPU 0 #endif #ifndef _GLIBCXX_PARALLEL_ASSERTIONS /** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code. * Should be switched on only locally. */ #define _GLIBCXX_PARALLEL_ASSERTIONS (_GLIBCXX_ASSERTIONS+0) #endif #ifndef _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 /** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code. * Consider the size of the L1 cache for * gnu_parallel::__parallel_random_shuffle(). */ #define _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 0 #endif #ifndef _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB /** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code. * Consider the size of the TLB for * gnu_parallel::__parallel_random_shuffle(). */ #define _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB 0 #endif 8/parallel/partial_sum.h000064400000016462152526447520011225 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/partial_sum.h * @brief Parallel implementation of std::partial_sum(), i.e. prefix * sums. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_PARTIAL_SUM_H #define _GLIBCXX_PARALLEL_PARTIAL_SUM_H 1 #include #include #include #include #include namespace __gnu_parallel { // Problem: there is no 0-element given. /** @brief Base case prefix sum routine. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __result Begin iterator of output sequence. * @param __bin_op Associative binary function. * @param __value Start value. Must be passed since the neutral * element is unknown in general. * @return End iterator of output sequence. */ template _OutputIterator __parallel_partial_sum_basecase(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, typename std::iterator_traits <_IIter>::value_type __value) { if (__begin == __end) return __result; while (__begin != __end) { __value = __bin_op(__value, *__begin); *__result = __value; ++__result; ++__begin; } return __result; } /** @brief Parallel partial sum implementation, two-phase approach, no recursion. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __result Begin iterator of output sequence. * @param __bin_op Associative binary function. * @param __n Length of sequence. * @return End iterator of output sequence. */ template _OutputIterator __parallel_partial_sum_linear(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, typename std::iterator_traits<_IIter>::difference_type __n) { typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; if (__begin == __end) return __result; _ThreadIndex __num_threads = std::min<_DifferenceType>(__get_max_threads(), __n - 1); if (__num_threads < 2) { *__result = *__begin; return __parallel_partial_sum_basecase(__begin + 1, __end, __result + 1, __bin_op, *__begin); } _DifferenceType* __borders; _ValueType* __sums; const _Settings& __s = _Settings::get(); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __borders = new _DifferenceType[__num_threads + 2]; if (__s.partial_sum_dilation == 1.0f) __equally_split(__n, __num_threads + 1, __borders); else { _DifferenceType __first_part_length = std::max<_DifferenceType>(1, __n / (1.0f + __s.partial_sum_dilation * __num_threads)); _DifferenceType __chunk_length = (__n - __first_part_length) / __num_threads; _DifferenceType __borderstart = __n - __num_threads * __chunk_length; __borders[0] = 0; for (_ThreadIndex __i = 1; __i < (__num_threads + 1); ++__i) { __borders[__i] = __borderstart; __borderstart += __chunk_length; } __borders[__num_threads + 1] = __n; } __sums = static_cast<_ValueType*>(::operator new(sizeof(_ValueType) * __num_threads)); _OutputIterator __target_end; } //single _ThreadIndex __iam = omp_get_thread_num(); if (__iam == 0) { *__result = *__begin; __parallel_partial_sum_basecase(__begin + 1, __begin + __borders[1], __result + 1, __bin_op, *__begin); ::new(&(__sums[__iam])) _ValueType(*(__result + __borders[1] - 1)); } else { ::new(&(__sums[__iam])) _ValueType(__gnu_parallel::accumulate( __begin + __borders[__iam] + 1, __begin + __borders[__iam + 1], *(__begin + __borders[__iam]), __bin_op, __gnu_parallel::sequential_tag())); } # pragma omp barrier # pragma omp single __parallel_partial_sum_basecase(__sums + 1, __sums + __num_threads, __sums + 1, __bin_op, __sums[0]); # pragma omp barrier // Still same team. __parallel_partial_sum_basecase(__begin + __borders[__iam + 1], __begin + __borders[__iam + 2], __result + __borders[__iam + 1], __bin_op, __sums[__iam]); } //parallel for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __sums[__i].~_ValueType(); ::operator delete(__sums); delete[] __borders; return __result + __n; } /** @brief Parallel partial sum front-__end. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __result Begin iterator of output sequence. * @param __bin_op Associative binary function. * @return End iterator of output sequence. */ template _OutputIterator __parallel_partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op) { _GLIBCXX_CALL(__begin - __end) typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; switch (_Settings::get().partial_sum_algorithm) { case LINEAR: // Need an initial offset. return __parallel_partial_sum_linear(__begin, __end, __result, __bin_op, __n); default: // Partial_sum algorithm not implemented. _GLIBCXX_PARALLEL_ASSERT(0); return __result + __n; } } } #endif /* _GLIBCXX_PARALLEL_PARTIAL_SUM_H */ 8/parallel/balanced_quicksort.h000064400000041070152526447520012533 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/balanced_quicksort.h * @brief Implementation of a dynamically load-balanced parallel quicksort. * * It works in-place and needs only logarithmic extra memory. * The algorithm is similar to the one proposed in * * P. Tsigas and Y. Zhang. * A simple, fast parallel implementation of quicksort and * its performance evaluation on SUN enterprise 10000. * In 11th Euromicro Conference on Parallel, Distributed and * Network-Based Processing, page 372, 2003. * * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_BALANCED_QUICKSORT_H #define _GLIBCXX_PARALLEL_BALANCED_QUICKSORT_H 1 #include #include #include #include #include #include #include #if _GLIBCXX_PARALLEL_ASSERTIONS #include #ifdef _GLIBCXX_HAVE_UNISTD_H #include #endif #endif namespace __gnu_parallel { /** @brief Information local to one thread in the parallel quicksort run. */ template struct _QSBThreadLocal { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; /** @brief Continuous part of the sequence, described by an iterator pair. */ typedef std::pair<_RAIter, _RAIter> _Piece; /** @brief Initial piece to work on. */ _Piece _M_initial; /** @brief Work-stealing queue. */ _RestrictedBoundedConcurrentQueue<_Piece> _M_leftover_parts; /** @brief Number of threads involved in this algorithm. */ _ThreadIndex _M_num_threads; /** @brief Pointer to a counter of elements left over to sort. */ volatile _DifferenceType* _M_elements_leftover; /** @brief The complete sequence to sort. */ _Piece _M_global; /** @brief Constructor. * @param __queue_size size of the work-stealing queue. */ _QSBThreadLocal(int __queue_size) : _M_leftover_parts(__queue_size) { } }; /** @brief Balanced quicksort divide step. * @param __begin Begin iterator of subsequence. * @param __end End iterator of subsequence. * @param __comp Comparator. * @param __num_threads Number of threads that are allowed to work on * this part. * @pre @c (__end-__begin)>=1 */ template typename std::iterator_traits<_RAIter>::difference_type __qsb_divide(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { _GLIBCXX_PARALLEL_ASSERT(__num_threads > 0); typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _RAIter __pivot_pos = __median_of_three_iterators(__begin, __begin + (__end - __begin) / 2, __end - 1, __comp); #if defined(_GLIBCXX_PARALLEL_ASSERTIONS) // Must be in between somewhere. _DifferenceType __n = __end - __begin; _GLIBCXX_PARALLEL_ASSERT((!__comp(*__pivot_pos, *__begin) && !__comp(*(__begin + __n / 2), *__pivot_pos)) || (!__comp(*__pivot_pos, *__begin) && !__comp(*(__end - 1), *__pivot_pos)) || (!__comp(*__pivot_pos, *(__begin + __n / 2)) && !__comp(*__begin, *__pivot_pos)) || (!__comp(*__pivot_pos, *(__begin + __n / 2)) && !__comp(*(__end - 1), *__pivot_pos)) || (!__comp(*__pivot_pos, *(__end - 1)) && !__comp(*__begin, *__pivot_pos)) || (!__comp(*__pivot_pos, *(__end - 1)) && !__comp(*(__begin + __n / 2), *__pivot_pos))); #endif // Swap pivot value to end. if (__pivot_pos != (__end - 1)) std::iter_swap(__pivot_pos, __end - 1); __pivot_pos = __end - 1; __gnu_parallel::__binder2nd<_Compare, _ValueType, _ValueType, bool> __pred(__comp, *__pivot_pos); // Divide, returning __end - __begin - 1 in the worst case. _DifferenceType __split_pos = __parallel_partition(__begin, __end - 1, __pred, __num_threads); // Swap back pivot to middle. std::iter_swap(__begin + __split_pos, __pivot_pos); __pivot_pos = __begin + __split_pos; #if _GLIBCXX_PARALLEL_ASSERTIONS _RAIter __r; for (__r = __begin; __r != __pivot_pos; ++__r) _GLIBCXX_PARALLEL_ASSERT(__comp(*__r, *__pivot_pos)); for (; __r != __end; ++__r) _GLIBCXX_PARALLEL_ASSERT(!__comp(*__r, *__pivot_pos)); #endif return __split_pos; } /** @brief Quicksort conquer step. * @param __tls Array of thread-local storages. * @param __begin Begin iterator of subsequence. * @param __end End iterator of subsequence. * @param __comp Comparator. * @param __iam Number of the thread processing this function. * @param __num_threads * Number of threads that are allowed to work on this part. */ template void __qsb_conquer(_QSBThreadLocal<_RAIter>** __tls, _RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __iam, _ThreadIndex __num_threads, bool __parent_wait) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; if (__num_threads <= 1 || __n <= 1) { __tls[__iam]->_M_initial.first = __begin; __tls[__iam]->_M_initial.second = __end; __qsb_local_sort_with_helping(__tls, __comp, __iam, __parent_wait); return; } // Divide step. _DifferenceType __split_pos = __qsb_divide(__begin, __end, __comp, __num_threads); #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(0 <= __split_pos && __split_pos < (__end - __begin)); #endif _ThreadIndex __num_threads_leftside = std::max<_ThreadIndex> (1, std::min<_ThreadIndex>(__num_threads - 1, __split_pos * __num_threads / __n)); # pragma omp atomic *__tls[__iam]->_M_elements_leftover -= (_DifferenceType)1; // Conquer step. # pragma omp parallel num_threads(2) { bool __wait; if(omp_get_num_threads() < 2) __wait = false; else __wait = __parent_wait; # pragma omp sections { # pragma omp section { __qsb_conquer(__tls, __begin, __begin + __split_pos, __comp, __iam, __num_threads_leftside, __wait); __wait = __parent_wait; } // The pivot_pos is left in place, to ensure termination. # pragma omp section { __qsb_conquer(__tls, __begin + __split_pos + 1, __end, __comp, __iam + __num_threads_leftside, __num_threads - __num_threads_leftside, __wait); __wait = __parent_wait; } } } } /** * @brief Quicksort step doing load-balanced local sort. * @param __tls Array of thread-local storages. * @param __comp Comparator. * @param __iam Number of the thread processing this function. */ template void __qsb_local_sort_with_helping(_QSBThreadLocal<_RAIter>** __tls, _Compare& __comp, _ThreadIndex __iam, bool __wait) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; typedef std::pair<_RAIter, _RAIter> _Piece; _QSBThreadLocal<_RAIter>& __tl = *__tls[__iam]; _DifferenceType __base_case_n = _Settings::get().sort_qsb_base_case_maximal_n; if (__base_case_n < 2) __base_case_n = 2; _ThreadIndex __num_threads = __tl._M_num_threads; // Every thread has its own random number generator. _RandomNumber __rng(__iam + 1); _Piece __current = __tl._M_initial; _DifferenceType __elements_done = 0; #if _GLIBCXX_PARALLEL_ASSERTIONS _DifferenceType __total_elements_done = 0; #endif for (;;) { // Invariant: __current must be a valid (maybe empty) range. _RAIter __begin = __current.first, __end = __current.second; _DifferenceType __n = __end - __begin; if (__n > __base_case_n) { // Divide. _RAIter __pivot_pos = __begin + __rng(__n); // Swap __pivot_pos value to end. if (__pivot_pos != (__end - 1)) std::iter_swap(__pivot_pos, __end - 1); __pivot_pos = __end - 1; __gnu_parallel::__binder2nd <_Compare, _ValueType, _ValueType, bool> __pred(__comp, *__pivot_pos); // Divide, leave pivot unchanged in last place. _RAIter __split_pos1, __split_pos2; __split_pos1 = __gnu_sequential::partition(__begin, __end - 1, __pred); // Left side: < __pivot_pos; __right side: >= __pivot_pos. #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__begin <= __split_pos1 && __split_pos1 < __end); #endif // Swap pivot back to middle. if (__split_pos1 != __pivot_pos) std::iter_swap(__split_pos1, __pivot_pos); __pivot_pos = __split_pos1; // In case all elements are equal, __split_pos1 == 0. if ((__split_pos1 + 1 - __begin) < (__n >> 7) || (__end - __split_pos1) < (__n >> 7)) { // Very unequal split, one part smaller than one 128th // elements not strictly larger than the pivot. __gnu_parallel::__unary_negate<__gnu_parallel::__binder1st <_Compare, _ValueType, _ValueType, bool>, _ValueType> __pred(__gnu_parallel::__binder1st <_Compare, _ValueType, _ValueType, bool> (__comp, *__pivot_pos)); // Find other end of pivot-equal range. __split_pos2 = __gnu_sequential::partition(__split_pos1 + 1, __end, __pred); } else // Only skip the pivot. __split_pos2 = __split_pos1 + 1; // Elements equal to pivot are done. __elements_done += (__split_pos2 - __split_pos1); #if _GLIBCXX_PARALLEL_ASSERTIONS __total_elements_done += (__split_pos2 - __split_pos1); #endif // Always push larger part onto stack. if (((__split_pos1 + 1) - __begin) < (__end - (__split_pos2))) { // Right side larger. if ((__split_pos2) != __end) __tl._M_leftover_parts.push_front (std::make_pair(__split_pos2, __end)); //__current.first = __begin; //already set anyway __current.second = __split_pos1; continue; } else { // Left side larger. if (__begin != __split_pos1) __tl._M_leftover_parts.push_front(std::make_pair (__begin, __split_pos1)); __current.first = __split_pos2; //__current.second = __end; //already set anyway continue; } } else { __gnu_sequential::sort(__begin, __end, __comp); __elements_done += __n; #if _GLIBCXX_PARALLEL_ASSERTIONS __total_elements_done += __n; #endif // Prefer own stack, small pieces. if (__tl._M_leftover_parts.pop_front(__current)) continue; # pragma omp atomic *__tl._M_elements_leftover -= __elements_done; __elements_done = 0; #if _GLIBCXX_PARALLEL_ASSERTIONS double __search_start = omp_get_wtime(); #endif // Look for new work. bool __successfully_stolen = false; while (__wait && *__tl._M_elements_leftover > 0 && !__successfully_stolen #if _GLIBCXX_PARALLEL_ASSERTIONS // Possible dead-lock. && (omp_get_wtime() < (__search_start + 1.0)) #endif ) { _ThreadIndex __victim; __victim = __rng(__num_threads); // Large pieces. __successfully_stolen = (__victim != __iam) && __tls[__victim]->_M_leftover_parts.pop_back(__current); if (!__successfully_stolen) __yield(); #if !defined(__ICC) && !defined(__ECC) # pragma omp flush #endif } #if _GLIBCXX_PARALLEL_ASSERTIONS if (omp_get_wtime() >= (__search_start + 1.0)) { sleep(1); _GLIBCXX_PARALLEL_ASSERT(omp_get_wtime() < (__search_start + 1.0)); } #endif if (!__successfully_stolen) { #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(*__tl._M_elements_leftover == 0); #endif return; } } } } /** @brief Top-level quicksort routine. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __comp Comparator. * @param __num_threads Number of threads that are allowed to work on * this part. */ template void __parallel_sort_qsb(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { _GLIBCXX_CALL(__end - __begin) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; typedef std::pair<_RAIter, _RAIter> _Piece; typedef _QSBThreadLocal<_RAIter> _TLSType; _DifferenceType __n = __end - __begin; if (__n <= 1) return; // At least one element per processor. if (__num_threads > __n) __num_threads = static_cast<_ThreadIndex>(__n); // Initialize thread local storage _TLSType** __tls = new _TLSType*[__num_threads]; _DifferenceType __queue_size = (__num_threads * (_ThreadIndex)(__rd_log2(__n) + 1)); for (_ThreadIndex __t = 0; __t < __num_threads; ++__t) __tls[__t] = new _QSBThreadLocal<_RAIter>(__queue_size); // There can never be more than ceil(__rd_log2(__n)) ranges on the // stack, because // 1. Only one processor pushes onto the stack // 2. The largest range has at most length __n // 3. Each range is larger than half of the range remaining volatile _DifferenceType __elements_leftover = __n; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) { __tls[__i]->_M_elements_leftover = &__elements_leftover; __tls[__i]->_M_num_threads = __num_threads; __tls[__i]->_M_global = std::make_pair(__begin, __end); // Just in case nothing is left to assign. __tls[__i]->_M_initial = std::make_pair(__end, __end); } // Main recursion call. __qsb_conquer(__tls, __begin, __begin + __n, __comp, 0, __num_threads, true); #if _GLIBCXX_PARALLEL_ASSERTIONS // All stack must be empty. _Piece __dummy; for (_ThreadIndex __i = 1; __i < __num_threads; ++__i) _GLIBCXX_PARALLEL_ASSERT( !__tls[__i]->_M_leftover_parts.pop_back(__dummy)); #endif for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) delete __tls[__i]; delete[] __tls; } } // namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_BALANCED_QUICKSORT_H */ 8/parallel/multiway_merge.h000064400000211607152526447520011735 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/multiway_merge.h * @brief Implementation of sequential and parallel multiway merge. * * Explanations on the high-speed merging routines in the appendix of * * P. Sanders. * Fast priority queues for cached memory. * ACM Journal of Experimental Algorithmics, 5, 2000. * * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Manuel Holtgrewe. #ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H #define _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H #include #include #include #include #include #include #if _GLIBCXX_PARALLEL_ASSERTIONS #include #endif /** @brief Length of a sequence described by a pair of iterators. */ #define _GLIBCXX_PARALLEL_LENGTH(__s) ((__s).second - (__s).first) namespace __gnu_parallel { template _OutputIterator __merge_advance(_RAIter1&, _RAIter1, _RAIter2&, _RAIter2, _OutputIterator, _DifferenceTp, _Compare); /** @brief _Iterator wrapper supporting an implicit supremum at the end * of the sequence, dominating all comparisons. * * The implicit supremum comes with a performance cost. * * Deriving from _RAIter is not possible since * _RAIter need not be a class. */ template class _GuardedIterator { private: /** @brief Current iterator __position. */ _RAIter _M_current; /** @brief End iterator of the sequence. */ _RAIter _M_end; /** @brief _Compare. */ _Compare& __comp; public: /** @brief Constructor. Sets iterator to beginning of sequence. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __comp Comparator provided for associated overloaded * compare operators. */ _GuardedIterator(_RAIter __begin, _RAIter __end, _Compare& __comp) : _M_current(__begin), _M_end(__end), __comp(__comp) { } /** @brief Pre-increment operator. * @return This. */ _GuardedIterator<_RAIter, _Compare>& operator++() { ++_M_current; return *this; } /** @brief Dereference operator. * @return Referenced element. */ typename std::iterator_traits<_RAIter>::value_type& operator*() { return *_M_current; } /** @brief Convert to wrapped iterator. * @return Wrapped iterator. */ operator _RAIter() { return _M_current; } /** @brief Compare two elements referenced by guarded iterators. * @param __bi1 First iterator. * @param __bi2 Second iterator. * @return @c true if less. */ friend bool operator<(_GuardedIterator<_RAIter, _Compare>& __bi1, _GuardedIterator<_RAIter, _Compare>& __bi2) { if (__bi1._M_current == __bi1._M_end) // __bi1 is sup return __bi2._M_current == __bi2._M_end; // __bi2 is not sup if (__bi2._M_current == __bi2._M_end) // __bi2 is sup return true; return (__bi1.__comp)(*__bi1, *__bi2); // normal compare } /** @brief Compare two elements referenced by guarded iterators. * @param __bi1 First iterator. * @param __bi2 Second iterator. * @return @c True if less equal. */ friend bool operator<=(_GuardedIterator<_RAIter, _Compare>& __bi1, _GuardedIterator<_RAIter, _Compare>& __bi2) { if (__bi2._M_current == __bi2._M_end) // __bi1 is sup return __bi1._M_current != __bi1._M_end; // __bi2 is not sup if (__bi1._M_current == __bi1._M_end) // __bi2 is sup return false; return !(__bi1.__comp)(*__bi2, *__bi1); // normal compare } }; template class _UnguardedIterator { private: /** @brief Current iterator __position. */ _RAIter _M_current; /** @brief _Compare. */ _Compare& __comp; public: /** @brief Constructor. Sets iterator to beginning of sequence. * @param __begin Begin iterator of sequence. * @param __end Unused, only for compatibility. * @param __comp Unused, only for compatibility. */ _UnguardedIterator(_RAIter __begin, _RAIter /* __end */, _Compare& __comp) : _M_current(__begin), __comp(__comp) { } /** @brief Pre-increment operator. * @return This. */ _UnguardedIterator<_RAIter, _Compare>& operator++() { ++_M_current; return *this; } /** @brief Dereference operator. * @return Referenced element. */ typename std::iterator_traits<_RAIter>::value_type& operator*() { return *_M_current; } /** @brief Convert to wrapped iterator. * @return Wrapped iterator. */ operator _RAIter() { return _M_current; } /** @brief Compare two elements referenced by unguarded iterators. * @param __bi1 First iterator. * @param __bi2 Second iterator. * @return @c true if less. */ friend bool operator<(_UnguardedIterator<_RAIter, _Compare>& __bi1, _UnguardedIterator<_RAIter, _Compare>& __bi2) { // Normal compare. return (__bi1.__comp)(*__bi1, *__bi2); } /** @brief Compare two elements referenced by unguarded iterators. * @param __bi1 First iterator. * @param __bi2 Second iterator. * @return @c True if less equal. */ friend bool operator<=(_UnguardedIterator<_RAIter, _Compare>& __bi1, _UnguardedIterator<_RAIter, _Compare>& __bi2) { // Normal compare. return !(__bi1.__comp)(*__bi2, *__bi1); } }; /** @brief Highly efficient 3-way merging procedure. * * Merging is done with the algorithm implementation described by Peter * Sanders. Basically, the idea is to minimize the number of necessary * comparison after merging an element. The implementation trick * that makes this fast is that the order of the sequences is stored * in the instruction pointer (translated into labels in C++). * * This works well for merging up to 4 sequences. * * Note that making the merging stable does @a not come at a * performance hit. * * Whether the merging is done guarded or unguarded is selected by the * used iterator class. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template class iterator, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> _RAIter3 multiway_merge_3_variant(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length); typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; if (__length == 0) return __target; #if _GLIBCXX_PARALLEL_ASSERTIONS _DifferenceTp __orig_length = __length; #endif iterator<_RAIter1, _Compare> __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp), __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp), __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp); if (__seq0 <= __seq1) { if (__seq1 <= __seq2) goto __s012; else if (__seq2 < __seq0) goto __s201; else goto __s021; } else { if (__seq1 <= __seq2) { if (__seq0 <= __seq2) goto __s102; else goto __s120; } else goto __s210; } #define _GLIBCXX_PARALLEL_MERGE_3_CASE(__a, __b, __c, __c0, __c1) \ __s ## __a ## __b ## __c : \ *__target = *__seq ## __a; \ ++__target; \ --__length; \ ++__seq ## __a; \ if (__length == 0) goto __finish; \ if (__seq ## __a __c0 __seq ## __b) goto __s ## __a ## __b ## __c; \ if (__seq ## __a __c1 __seq ## __c) goto __s ## __b ## __a ## __c; \ goto __s ## __b ## __c ## __a; _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 1, 2, <=, <=); _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 2, 0, <=, < ); _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 0, 1, < , < ); _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 0, 2, < , <=); _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 2, 1, <=, <=); _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 1, 0, < , < ); #undef _GLIBCXX_PARALLEL_MERGE_3_CASE __finish: ; #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT( ((_RAIter1)__seq0 - __seqs_begin[0].first) + ((_RAIter1)__seq1 - __seqs_begin[1].first) + ((_RAIter1)__seq2 - __seqs_begin[2].first) == __orig_length); #endif __seqs_begin[0].first = __seq0; __seqs_begin[1].first = __seq1; __seqs_begin[2].first = __seq2; return __target; } /** * @brief Highly efficient 4-way merging procedure. * * Merging is done with the algorithm implementation described by Peter * Sanders. Basically, the idea is to minimize the number of necessary * comparison after merging an element. The implementation trick * that makes this fast is that the order of the sequences is stored * in the instruction pointer (translated into goto labels in C++). * * This works well for merging up to 4 sequences. * * Note that making the merging stable does @a not come at a * performance hit. * * Whether the merging is done guarded or unguarded is selected by the * used iterator class. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template class iterator, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> _RAIter3 multiway_merge_4_variant(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length); typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; iterator<_RAIter1, _Compare> __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp), __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp), __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp), __seq3(__seqs_begin[3].first, __seqs_begin[3].second, __comp); #define _GLIBCXX_PARALLEL_DECISION(__a, __b, __c, __d) { \ if (__seq ## __d < __seq ## __a) \ goto __s ## __d ## __a ## __b ## __c; \ if (__seq ## __d < __seq ## __b) \ goto __s ## __a ## __d ## __b ## __c; \ if (__seq ## __d < __seq ## __c) \ goto __s ## __a ## __b ## __d ## __c; \ goto __s ## __a ## __b ## __c ## __d; } if (__seq0 <= __seq1) { if (__seq1 <= __seq2) _GLIBCXX_PARALLEL_DECISION(0,1,2,3) else if (__seq2 < __seq0) _GLIBCXX_PARALLEL_DECISION(2,0,1,3) else _GLIBCXX_PARALLEL_DECISION(0,2,1,3) } else { if (__seq1 <= __seq2) { if (__seq0 <= __seq2) _GLIBCXX_PARALLEL_DECISION(1,0,2,3) else _GLIBCXX_PARALLEL_DECISION(1,2,0,3) } else _GLIBCXX_PARALLEL_DECISION(2,1,0,3) } #define _GLIBCXX_PARALLEL_MERGE_4_CASE(__a, __b, __c, __d, \ __c0, __c1, __c2) \ __s ## __a ## __b ## __c ## __d: \ if (__length == 0) goto __finish; \ *__target = *__seq ## __a; \ ++__target; \ --__length; \ ++__seq ## __a; \ if (__seq ## __a __c0 __seq ## __b) \ goto __s ## __a ## __b ## __c ## __d; \ if (__seq ## __a __c1 __seq ## __c) \ goto __s ## __b ## __a ## __c ## __d; \ if (__seq ## __a __c2 __seq ## __d) \ goto __s ## __b ## __c ## __a ## __d; \ goto __s ## __b ## __c ## __d ## __a; _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 2, 3, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 3, 2, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 1, 3, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 3, 1, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 1, 2, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 2, 1, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 2, 3, < , <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 3, 2, < , <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 0, 3, <=, < , <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 3, 0, <=, <=, < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 0, 2, <=, < , <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 2, 0, <=, <=, < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 1, 3, < , < , <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 3, 1, < , <=, < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 0, 3, < , < , <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 3, 0, < , <=, < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 0, 1, <=, < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 1, 0, <=, < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 1, 2, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 2, 1, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 0, 2, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 2, 0, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 0, 1, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 1, 0, < , < , < ); #undef _GLIBCXX_PARALLEL_MERGE_4_CASE #undef _GLIBCXX_PARALLEL_DECISION __finish: ; __seqs_begin[0].first = __seq0; __seqs_begin[1].first = __seq1; __seqs_begin[2].first = __seq2; __seqs_begin[3].first = __seq3; return __target; } /** @brief Multi-way merging procedure for a high branching factor, * guarded case. * * This merging variant uses a LoserTree class as selected by _LT. * * Stability is selected through the used LoserTree class _LT. * * At least one non-empty sequence is required. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template _RAIter3 multiway_merge_loser_tree(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin); _LT __lt(__k, __comp); // Default value for potentially non-default-constructible types. _ValueType* __arbitrary_element = 0; for (_SeqNumber __t = 0; __t < __k; ++__t) { if(!__arbitrary_element && _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__t]) > 0) __arbitrary_element = &(*__seqs_begin[__t].first); } for (_SeqNumber __t = 0; __t < __k; ++__t) { if (__seqs_begin[__t].first == __seqs_begin[__t].second) __lt.__insert_start(*__arbitrary_element, __t, true); else __lt.__insert_start(*__seqs_begin[__t].first, __t, false); } __lt.__init(); _SeqNumber __source; for (_DifferenceType __i = 0; __i < __length; ++__i) { //take out __source = __lt.__get_min_source(); *(__target++) = *(__seqs_begin[__source].first++); // Feed. if (__seqs_begin[__source].first == __seqs_begin[__source].second) __lt.__delete_min_insert(*__arbitrary_element, true); else // Replace from same __source. __lt.__delete_min_insert(*__seqs_begin[__source].first, false); } return __target; } /** @brief Multi-way merging procedure for a high branching factor, * unguarded case. * * Merging is done using the LoserTree class _LT. * * Stability is selected by the used LoserTrees. * * @pre No input will run out of elements during the merge. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template _RAIter3 multiway_merge_loser_tree_unguarded(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; _SeqNumber __k = __seqs_end - __seqs_begin; _LT __lt(__k, __sentinel, __comp); for (_SeqNumber __t = 0; __t < __k; ++__t) { #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__seqs_begin[__t].first != __seqs_begin[__t].second); #endif __lt.__insert_start(*__seqs_begin[__t].first, __t, false); } __lt.__init(); _SeqNumber __source; #if _GLIBCXX_PARALLEL_ASSERTIONS _DifferenceType __i = 0; #endif _RAIter3 __target_end = __target + __length; while (__target < __target_end) { // Take out. __source = __lt.__get_min_source(); #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(0 <= __source && __source < __k); _GLIBCXX_PARALLEL_ASSERT(__i == 0 || !__comp(*(__seqs_begin[__source].first), *(__target - 1))); #endif // Feed. *(__target++) = *(__seqs_begin[__source].first++); #if _GLIBCXX_PARALLEL_ASSERTIONS ++__i; #endif // Replace from same __source. __lt.__delete_min_insert(*__seqs_begin[__source].first, false); } return __target; } /** @brief Multi-way merging procedure for a high branching factor, * requiring sentinels to exist. * * @tparam UnguardedLoserTree _Loser Tree variant to use for the unguarded * merging. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template _RAIter3 multiway_merge_loser_tree_sentinel(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef std::iterator_traits<_RAIterIterator> _TraitsType; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; _RAIter3 __target_end; for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s) // Move the sequence ends to the sentinel. This has the // effect that the sentinel appears to be within the sequence. Then, // we can use the unguarded variant if we merge out as many // non-sentinel elements as we have. ++((*__s).second); __target_end = multiway_merge_loser_tree_unguarded (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp); #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__target_end == __target + __length); _GLIBCXX_PARALLEL_ASSERT(__is_sorted(__target, __target_end, __comp)); #endif // Restore the sequence ends so the sentinels are not contained in the // sequence any more (see comment in loop above). for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s) --((*__s).second); return __target_end; } /** * @brief Traits for determining whether the loser tree should * use pointers or copies. * * The field "_M_use_pointer" is used to determine whether to use pointers * in he loser trees or whether to copy the values into the loser tree. * * The default behavior is to use pointers if the data type is 4 times as * big as the pointer to it. * * Specialize for your data type to customize the behavior. * * Example: * * template<> * struct _LoserTreeTraits * { static const bool _M_use_pointer = false; }; * * template<> * struct _LoserTreeTraits * { static const bool _M_use_pointer = true; }; * * @param _Tp type to give the loser tree traits for. */ template struct _LoserTreeTraits { /** * @brief True iff to use pointers instead of values in loser trees. * * The default behavior is to use pointers if the data type is four * times as big as the pointer to it. */ static const bool _M_use_pointer = (sizeof(_Tp) > 4 * sizeof(_Tp*)); }; /** * @brief Switch for 3-way merging with __sentinels turned off. * * Note that 3-way merging is always stable! */ template struct __multiway_merge_3_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { return multiway_merge_3_variant<_GuardedIterator> (__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** * @brief Switch for 3-way merging with __sentinels turned on. * * Note that 3-way merging is always stable! */ template struct __multiway_merge_3_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { return multiway_merge_3_variant<_UnguardedIterator> (__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** * @brief Switch for 4-way merging with __sentinels turned off. * * Note that 4-way merging is always stable! */ template struct __multiway_merge_4_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { return multiway_merge_4_variant<_GuardedIterator> (__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** * @brief Switch for 4-way merging with __sentinels turned on. * * Note that 4-way merging is always stable! */ template struct __multiway_merge_4_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { return multiway_merge_4_variant<_UnguardedIterator> (__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** * @brief Switch for k-way merging with __sentinels turned on. */ template struct __multiway_merge_k_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; return multiway_merge_loser_tree_sentinel< typename __gnu_cxx::__conditional_type< _LoserTreeTraits<_ValueType>::_M_use_pointer, _LoserTreePointerUnguarded<__stable, _ValueType, _Compare>, _LoserTreeUnguarded<__stable, _ValueType, _Compare> >::__type> (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp); } }; /** * @brief Switch for k-way merging with __sentinels turned off. */ template struct __multiway_merge_k_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; return multiway_merge_loser_tree< typename __gnu_cxx::__conditional_type< _LoserTreeTraits<_ValueType>::_M_use_pointer, _LoserTreePointer<__stable, _ValueType, _Compare>, _LoserTree<__stable, _ValueType, _Compare> >::__type >(__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** @brief Sequential multi-way merging switch. * * The _GLIBCXX_PARALLEL_DECISION is based on the branching factor and * runtime settings. * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, possibly larger than the * number of elements available. * @param __sentinel The sequences have __a __sentinel element. * @return End iterator of output sequence. */ template _RAIter3 __sequential_multiway_merge(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; #if _GLIBCXX_PARALLEL_ASSERTIONS for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s) { _GLIBCXX_PARALLEL_ASSERT(__is_sorted((*__s).first, (*__s).second, __comp)); } #endif _DifferenceTp __total_length = 0; for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s) __total_length += _GLIBCXX_PARALLEL_LENGTH(*__s); __length = std::min<_DifferenceTp>(__length, __total_length); if(__length == 0) return __target; _RAIter3 __return_target = __target; _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin); switch (__k) { case 0: break; case 1: __return_target = std::copy(__seqs_begin[0].first, __seqs_begin[0].first + __length, __target); __seqs_begin[0].first += __length; break; case 2: __return_target = __merge_advance(__seqs_begin[0].first, __seqs_begin[0].second, __seqs_begin[1].first, __seqs_begin[1].second, __target, __length, __comp); break; case 3: __return_target = __multiway_merge_3_variant_sentinel_switch <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>() (__seqs_begin, __seqs_end, __target, __length, __comp); break; case 4: __return_target = __multiway_merge_4_variant_sentinel_switch <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>() (__seqs_begin, __seqs_end, __target, __length, __comp); break; default: __return_target = __multiway_merge_k_variant_sentinel_switch <__sentinels, __stable, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>() (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp); break; } #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT( __is_sorted(__target, __target + __length, __comp)); #endif return __return_target; } /** * @brief Stable sorting functor. * * Used to reduce code instanciation in multiway_merge_sampling_splitting. */ template struct _SamplingSorter { void operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp) { __gnu_sequential::stable_sort(__first, __last, __comp); } }; /** * @brief Non-__stable sorting functor. * * Used to reduce code instantiation in multiway_merge_sampling_splitting. */ template struct _SamplingSorter { void operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp) { __gnu_sequential::sort(__first, __last, __comp); } }; /** * @brief Sampling based splitting for parallel multiway-merge routine. */ template void multiway_merge_sampling_splitting(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _DifferenceType __length, _DifferenceType __total_length, _Compare __comp, std::vector > *__pieces) { typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; // __k sequences. const _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin); const _ThreadIndex __num_threads = omp_get_num_threads(); const _DifferenceType __num_samples = __gnu_parallel::_Settings::get().merge_oversampling * __num_threads; _ValueType* __samples = static_cast<_ValueType*> (::operator new(sizeof(_ValueType) * __k * __num_samples)); // Sample. for (_SeqNumber __s = 0; __s < __k; ++__s) for (_DifferenceType __i = 0; __i < __num_samples; ++__i) { _DifferenceType sample_index = static_cast<_DifferenceType> (_GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__s]) * (double(__i + 1) / (__num_samples + 1)) * (double(__length) / __total_length)); new(&(__samples[__s * __num_samples + __i])) _ValueType(__seqs_begin[__s].first[sample_index]); } // Sort stable or non-stable, depending on value of template parameter // "__stable". _SamplingSorter<__stable, _ValueType*, _Compare>() (__samples, __samples + (__num_samples * __k), __comp); for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab) // For each slab / processor. for (_SeqNumber __seq = 0; __seq < __k; ++__seq) { // For each sequence. if (__slab > 0) __pieces[__slab][__seq].first = std::upper_bound (__seqs_begin[__seq].first, __seqs_begin[__seq].second, __samples[__num_samples * __k * __slab / __num_threads], __comp) - __seqs_begin[__seq].first; else // Absolute beginning. __pieces[__slab][__seq].first = 0; if ((__slab + 1) < __num_threads) __pieces[__slab][__seq].second = std::upper_bound (__seqs_begin[__seq].first, __seqs_begin[__seq].second, __samples[__num_samples * __k * (__slab + 1) / __num_threads], __comp) - __seqs_begin[__seq].first; else // Absolute end. __pieces[__slab][__seq].second = _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]); } for (_SeqNumber __s = 0; __s < __k; ++__s) for (_DifferenceType __i = 0; __i < __num_samples; ++__i) __samples[__s * __num_samples + __i].~_ValueType(); ::operator delete(__samples); } /** * @brief Exact splitting for parallel multiway-merge routine. * * None of the passed sequences may be empty. */ template void multiway_merge_exact_splitting(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _DifferenceType __length, _DifferenceType __total_length, _Compare __comp, std::vector > *__pieces) { typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; const bool __tight = (__total_length == __length); // __k sequences. const _SeqNumber __k = __seqs_end - __seqs_begin; const _ThreadIndex __num_threads = omp_get_num_threads(); // (Settings::multiway_merge_splitting // == __gnu_parallel::_Settings::EXACT). std::vector<_RAIter1>* __offsets = new std::vector<_RAIter1>[__num_threads]; std::vector > __se(__k); copy(__seqs_begin, __seqs_end, __se.begin()); _DifferenceType* __borders = new _DifferenceType[__num_threads + 1]; __equally_split(__length, __num_threads, __borders); for (_ThreadIndex __s = 0; __s < (__num_threads - 1); ++__s) { __offsets[__s].resize(__k); multiseq_partition(__se.begin(), __se.end(), __borders[__s + 1], __offsets[__s].begin(), __comp); // Last one also needed and available. if (!__tight) { __offsets[__num_threads - 1].resize(__k); multiseq_partition(__se.begin(), __se.end(), _DifferenceType(__length), __offsets[__num_threads - 1].begin(), __comp); } } delete[] __borders; for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab) { // For each slab / processor. for (_SeqNumber __seq = 0; __seq < __k; ++__seq) { // For each sequence. if (__slab == 0) { // Absolute beginning. __pieces[__slab][__seq].first = 0; } else __pieces[__slab][__seq].first = __pieces[__slab - 1][__seq].second; if (!__tight || __slab < (__num_threads - 1)) __pieces[__slab][__seq].second = __offsets[__slab][__seq] - __seqs_begin[__seq].first; else { // __slab == __num_threads - 1 __pieces[__slab][__seq].second = _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]); } } } delete[] __offsets; } /** @brief Parallel multi-way merge routine. * * The _GLIBCXX_PARALLEL_DECISION is based on the branching factor * and runtime settings. * * Must not be called if the number of sequences is 1. * * @tparam _Splitter functor to split input (either __exact or sampling based) * @tparam __stable Stable merging incurs a performance penalty. * @tparam __sentinel Ignored. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, possibly larger than the * number of elements available. * @return End iterator of output sequence. */ template _RAIter3 parallel_multiway_merge(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _Splitter __splitter, _DifferenceTp __length, _Compare __comp, _ThreadIndex __num_threads) { #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__seqs_end - __seqs_begin > 1); #endif _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; // Leave only non-empty sequences. typedef std::pair<_RAIter1, _RAIter1> seq_type; seq_type* __ne_seqs = new seq_type[__seqs_end - __seqs_begin]; _SeqNumber __k = 0; _DifferenceType __total_length = 0; for (_RAIterIterator __raii = __seqs_begin; __raii != __seqs_end; ++__raii) { _DifferenceTp __seq_length = _GLIBCXX_PARALLEL_LENGTH(*__raii); if(__seq_length > 0) { __total_length += __seq_length; __ne_seqs[__k++] = *__raii; } } _GLIBCXX_CALL(__total_length) __length = std::min<_DifferenceTp>(__length, __total_length); if (__total_length == 0 || __k == 0) { delete[] __ne_seqs; return __target; } std::vector >* __pieces; __num_threads = static_cast<_ThreadIndex> (std::min<_DifferenceType>(__num_threads, __total_length)); # pragma omp parallel num_threads (__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); // Thread __t will have to merge pieces[__iam][0..__k - 1] __pieces = new std::vector< std::pair<_DifferenceType, _DifferenceType> >[__num_threads]; for (_ThreadIndex __s = 0; __s < __num_threads; ++__s) __pieces[__s].resize(__k); _DifferenceType __num_samples = __gnu_parallel::_Settings::get().merge_oversampling * __num_threads; __splitter(__ne_seqs, __ne_seqs + __k, __length, __total_length, __comp, __pieces); } //single _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __target_position = 0; for (_SeqNumber __c = 0; __c < __k; ++__c) __target_position += __pieces[__iam][__c].first; seq_type* __chunks = new seq_type[__k]; for (_SeqNumber __s = 0; __s < __k; ++__s) __chunks[__s] = std::make_pair(__ne_seqs[__s].first + __pieces[__iam][__s].first, __ne_seqs[__s].first + __pieces[__iam][__s].second); if(__length > __target_position) __sequential_multiway_merge<__stable, __sentinels> (__chunks, __chunks + __k, __target + __target_position, *(__seqs_begin->second), __length - __target_position, __comp); delete[] __chunks; } // parallel #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT( __is_sorted(__target, __target + __length, __comp)); #endif __k = 0; // Update ends of sequences. for (_RAIterIterator __raii = __seqs_begin; __raii != __seqs_end; ++__raii) { _DifferenceTp __length = _GLIBCXX_PARALLEL_LENGTH(*__raii); if(__length > 0) (*__raii).first += __pieces[__num_threads - 1][__k++].second; } delete[] __pieces; delete[] __ne_seqs; return __target + __length; } /** * @brief Multiway Merge Frontend. * * Merge the sequences specified by seqs_begin and __seqs_end into * __target. __seqs_begin and __seqs_end must point to a sequence of * pairs. These pairs must contain an iterator to the beginning * of a sequence in their first entry and an iterator the _M_end of * the same sequence in their second entry. * * Ties are broken arbitrarily. See stable_multiway_merge for a variant * that breaks ties by sequence number but is slower. * * The first entries of the pairs (i.e. the begin iterators) will be moved * forward. * * The output sequence has to provide enough space for all elements * that are written to it. * * This function will merge the input sequences: * * - not stable * - parallel, depending on the input size and Settings * - using sampling for splitting * - not using sentinels * * Example: * *
   *   int sequences[10][10];
   *   for (int __i = 0; __i < 10; ++__i)
   *     for (int __j = 0; __i < 10; ++__j)
   *       sequences[__i][__j] = __j;
   *
   *   int __out[33];
   *   std::vector > seqs;
   *   for (int __i = 0; __i < 10; ++__i)
   *     { seqs.push(std::make_pair(sequences[__i],
   *                                      sequences[__i] + 10)) }
   *
   *   multiway_merge(seqs.begin(), seqs.end(), __target, std::less(), 33);
   * 
* * @see stable_multiway_merge * * @pre All input sequences must be sorted. * @pre Target must provide enough space to merge out length elements or * the number of elements in all sequences, whichever is smaller. * * @post [__target, return __value) contains merged __elements from the * input sequences. * @post return __value - __target = min(__length, number of elements in all * sequences). * * @tparam _RAIterPairIterator iterator over sequence * of pairs of iterators * @tparam _RAIterOut iterator over target sequence * @tparam _DifferenceTp difference type for the sequence * @tparam _Compare strict weak ordering type to compare elements * in sequences * * @param __seqs_begin __begin of sequence __sequence * @param __seqs_end _M_end of sequence __sequence * @param __target target sequence to merge to. * @param __comp strict weak ordering to use for element comparison. * @param __length Maximum length to merge, possibly larger than the * number of elements available. * * @return _M_end iterator of output sequence */ // multiway_merge // public interface template _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute multiway merge *sequentially*. return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::exact_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sampling_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, parallel_tag __tag = parallel_tag(0)) { return multiway_merge(__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // public interface template _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, default_parallel_tag __tag) { return multiway_merge(__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // stable_multiway_merge // public interface template _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute multiway merge *sequentially*. return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::exact_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, sampling_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_sampling_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, parallel_tag __tag = parallel_tag(0)) { return stable_multiway_merge (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // public interface template _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, default_parallel_tag __tag) { return stable_multiway_merge (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } /** * @brief Multiway Merge Frontend. * * Merge the sequences specified by seqs_begin and __seqs_end into * __target. __seqs_begin and __seqs_end must point to a sequence of * pairs. These pairs must contain an iterator to the beginning * of a sequence in their first entry and an iterator the _M_end of * the same sequence in their second entry. * * Ties are broken arbitrarily. See stable_multiway_merge for a variant * that breaks ties by sequence number but is slower. * * The first entries of the pairs (i.e. the begin iterators) will be moved * forward accordingly. * * The output sequence has to provide enough space for all elements * that are written to it. * * This function will merge the input sequences: * * - not stable * - parallel, depending on the input size and Settings * - using sampling for splitting * - using sentinels * * You have to take care that the element the _M_end iterator points to is * readable and contains a value that is greater than any other non-sentinel * value in all sequences. * * Example: * *
   *   int sequences[10][11];
   *   for (int __i = 0; __i < 10; ++__i)
   *     for (int __j = 0; __i < 11; ++__j)
   *       sequences[__i][__j] = __j; // __last one is sentinel!
   *
   *   int __out[33];
   *   std::vector > seqs;
   *   for (int __i = 0; __i < 10; ++__i)
   *     { seqs.push(std::make_pair(sequences[__i],
   *                                      sequences[__i] + 10)) }
   *
   *   multiway_merge(seqs.begin(), seqs.end(), __target, std::less(), 33);
   * 
* * @pre All input sequences must be sorted. * @pre Target must provide enough space to merge out length elements or * the number of elements in all sequences, whichever is smaller. * @pre For each @c __i, @c __seqs_begin[__i].second must be the end * marker of the sequence, but also reference the one more __sentinel * element. * * @post [__target, return __value) contains merged __elements from the * input sequences. * @post return __value - __target = min(__length, number of elements in all * sequences). * * @see stable_multiway_merge_sentinels * * @tparam _RAIterPairIterator iterator over sequence * of pairs of iterators * @tparam _RAIterOut iterator over target sequence * @tparam _DifferenceTp difference type for the sequence * @tparam _Compare strict weak ordering type to compare elements * in sequences * * @param __seqs_begin __begin of sequence __sequence * @param __seqs_end _M_end of sequence __sequence * @param __target target sequence to merge to. * @param __comp strict weak ordering to use for element comparison. * @param __length Maximum length to merge, possibly larger than the * number of elements available. * * @return _M_end iterator of output sequence */ // multiway_merge_sentinels // public interface template _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute multiway merge *sequentially*. return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::exact_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, sampling_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_sampling_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge ( __seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, parallel_tag __tag = parallel_tag(0)) { return multiway_merge_sentinels (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // public interface template _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, default_parallel_tag __tag) { return multiway_merge_sentinels (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // stable_multiway_merge_sentinels // public interface template _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute multiway merge *sequentially*. return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::exact_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, sampling_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge (__seqs_begin, __seqs_end, __target, multiway_merge_sampling_splitting ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, parallel_tag __tag = parallel_tag(0)) { return stable_multiway_merge_sentinels (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // public interface template _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, default_parallel_tag __tag) { return stable_multiway_merge_sentinels (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } }; // namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H */ 8/parallel/find_selectors.h000064400000015520152526447520011702 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file parallel/find_selectors.h * @brief _Function objects representing different tasks to be plugged * into the parallel find algorithm. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_FIND_SELECTORS_H #define _GLIBCXX_PARALLEL_FIND_SELECTORS_H 1 #include #include #include namespace __gnu_parallel { /** @brief Base class of all __gnu_parallel::__find_template selectors. */ struct __generic_find_selector { }; /** * @brief Test predicate on a single element, used for std::find() * and std::find_if (). */ struct __find_if_selector : public __generic_find_selector { /** @brief Test on one position. * @param __i1 _Iterator on first sequence. * @param __i2 _Iterator on second sequence (unused). * @param __pred Find predicate. */ template bool operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) { return __pred(*__i1); } /** @brief Corresponding sequential algorithm on a sequence. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __pred Find predicate. */ template std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred) { return std::make_pair(find_if(__begin1, __end1, __pred, sequential_tag()), __begin2); } }; /** @brief Test predicate on two adjacent elements. */ struct __adjacent_find_selector : public __generic_find_selector { /** @brief Test on one position. * @param __i1 _Iterator on first sequence. * @param __i2 _Iterator on second sequence (unused). * @param __pred Find predicate. */ template bool operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) { // Passed end iterator is one short. return __pred(*__i1, *(__i1 + 1)); } /** @brief Corresponding sequential algorithm on a sequence. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __pred Find predicate. */ template std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred) { // Passed end iterator is one short. _RAIter1 __spot = adjacent_find(__begin1, __end1 + 1, __pred, sequential_tag()); if (__spot == (__end1 + 1)) __spot = __end1; return std::make_pair(__spot, __begin2); } }; /** @brief Test inverted predicate on a single element. */ struct __mismatch_selector : public __generic_find_selector { /** * @brief Test on one position. * @param __i1 _Iterator on first sequence. * @param __i2 _Iterator on second sequence (unused). * @param __pred Find predicate. */ template bool operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) { return !__pred(*__i1, *__i2); } /** * @brief Corresponding sequential algorithm on a sequence. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __pred Find predicate. */ template std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred) { return mismatch(__begin1, __end1, __begin2, __pred, sequential_tag()); } }; /** @brief Test predicate on several elements. */ template struct __find_first_of_selector : public __generic_find_selector { _FIterator _M_begin; _FIterator _M_end; explicit __find_first_of_selector(_FIterator __begin, _FIterator __end) : _M_begin(__begin), _M_end(__end) { } /** @brief Test on one position. * @param __i1 _Iterator on first sequence. * @param __i2 _Iterator on second sequence (unused). * @param __pred Find predicate. */ template bool operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) { for (_FIterator __pos_in_candidates = _M_begin; __pos_in_candidates != _M_end; ++__pos_in_candidates) if (__pred(*__i1, *__pos_in_candidates)) return true; return false; } /** @brief Corresponding sequential algorithm on a sequence. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __pred Find predicate. */ template std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred) { return std::make_pair(find_first_of(__begin1, __end1, _M_begin, _M_end, __pred, sequential_tag()), __begin2); } }; } #endif /* _GLIBCXX_PARALLEL_FIND_SELECTORS_H */ 8/parallel/tags.h000064400000013536152526447520007642 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** * @file parallel/tags.h * @brief Tags for compile-time selection. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_TAGS_H #define _GLIBCXX_PARALLEL_TAGS_H 1 #include #include namespace __gnu_parallel { /** @brief Forces sequential execution at compile time. */ struct sequential_tag { }; /** @brief Recommends parallel execution at compile time, * optionally using a user-specified number of threads. */ struct parallel_tag { private: _ThreadIndex _M_num_threads; public: /** @brief Default constructor. Use default number of threads. */ parallel_tag() { _M_num_threads = 0; } /** @brief Default constructor. Recommend number of threads to use. * @param __num_threads Desired number of threads. */ parallel_tag(_ThreadIndex __num_threads) { _M_num_threads = __num_threads; } /** @brief Find out desired number of threads. * @return Desired number of threads. */ _ThreadIndex __get_num_threads() { if(_M_num_threads == 0) return omp_get_max_threads(); else return _M_num_threads; } /** @brief Set the desired number of threads. * @param __num_threads Desired number of threads. */ void set_num_threads(_ThreadIndex __num_threads) { _M_num_threads = __num_threads; } }; /** @brief Recommends parallel execution using the default parallel algorithm. */ struct default_parallel_tag : public parallel_tag { default_parallel_tag() { } default_parallel_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Recommends parallel execution using dynamic load-balancing at compile time. */ struct balanced_tag : public parallel_tag { }; /** @brief Recommends parallel execution using static load-balancing at compile time. */ struct unbalanced_tag : public parallel_tag { }; /** @brief Recommends parallel execution using OpenMP dynamic load-balancing at compile time. */ struct omp_loop_tag : public parallel_tag { }; /** @brief Recommends parallel execution using OpenMP static load-balancing at compile time. */ struct omp_loop_static_tag : public parallel_tag { }; /** @brief Base class for for std::find() variants. */ struct find_tag { }; /** @brief Forces parallel merging * with exact splitting, at compile time. */ struct exact_tag : public parallel_tag { exact_tag() { } exact_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel merging * with exact splitting, at compile time. */ struct sampling_tag : public parallel_tag { sampling_tag() { } sampling_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using multiway mergesort * at compile time. */ struct multiway_mergesort_tag : public parallel_tag { multiway_mergesort_tag() { } multiway_mergesort_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using multiway mergesort * with exact splitting at compile time. */ struct multiway_mergesort_exact_tag : public parallel_tag { multiway_mergesort_exact_tag() { } multiway_mergesort_exact_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using multiway mergesort * with splitting by sampling at compile time. */ struct multiway_mergesort_sampling_tag : public parallel_tag { multiway_mergesort_sampling_tag() { } multiway_mergesort_sampling_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using unbalanced quicksort * at compile time. */ struct quicksort_tag : public parallel_tag { quicksort_tag() { } quicksort_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using balanced quicksort * at compile time. */ struct balanced_quicksort_tag : public parallel_tag { balanced_quicksort_tag() { } balanced_quicksort_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Selects the growing block size variant for std::find(). @see _GLIBCXX_FIND_GROWING_BLOCKS */ struct growing_blocks_tag : public find_tag { }; /** @brief Selects the constant block size variant for std::find(). @see _GLIBCXX_FIND_CONSTANT_SIZE_BLOCKS */ struct constant_size_blocks_tag : public find_tag { }; /** @brief Selects the equal splitting variant for std::find(). @see _GLIBCXX_FIND_EQUAL_SPLIT */ struct equal_split_tag : public find_tag { }; } #endif /* _GLIBCXX_PARALLEL_TAGS_H */ 8/valarray000064400000116522152526447520006502 0ustar00// The template and inlines for the -*- C++ -*- valarray class. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/valarray * This is a Standard C++ Library header. */ // Written by Gabriel Dos Reis #ifndef _GLIBCXX_VALARRAY #define _GLIBCXX_VALARRAY 1 #pragma GCC system_header #include #include #include #include #if __cplusplus >= 201103L #include #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template class _Expr; template class _ValArray; template class _Meta, class _Dom> struct _UnClos; template class _Meta1, template class _Meta2, class _Dom1, class _Dom2> class _BinClos; template class _Meta, class _Dom> class _SClos; template class _Meta, class _Dom> class _GClos; template class _Meta, class _Dom> class _IClos; template class _Meta, class _Dom> class _ValFunClos; template class _Meta, class _Dom> class _RefFunClos; template class valarray; // An array of type _Tp class slice; // BLAS-like slice out of an array template class slice_array; class gslice; // generalized slice out of an array template class gslice_array; template class mask_array; // masked array template class indirect_array; // indirected array _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup numeric_arrays Numeric Arrays * @ingroup numerics * * Classes and functions for representing and manipulating arrays of elements. * @{ */ /** * @brief Smart array designed to support numeric processing. * * A valarray is an array that provides constraints intended to allow for * effective optimization of numeric array processing by reducing the * aliasing that can result from pointer representations. It represents a * one-dimensional array from which different multidimensional subsets can * be accessed and modified. * * @tparam _Tp Type of object in the array. */ template class valarray { template struct _UnaryOp { typedef typename __fun<_Op, _Tp>::result_type __rt; typedef _Expr<_UnClos<_Op, _ValArray, _Tp>, __rt> _Rt; }; public: typedef _Tp value_type; // _lib.valarray.cons_ construct/destroy: /// Construct an empty array. valarray(); /// Construct an array with @a n elements. explicit valarray(size_t); /// Construct an array with @a n elements initialized to @a t. valarray(const _Tp&, size_t); /// Construct an array initialized to the first @a n elements of @a t. valarray(const _Tp* __restrict__, size_t); /// Copy constructor. valarray(const valarray&); #if __cplusplus >= 201103L /// Move constructor. valarray(valarray&&) noexcept; #endif /// Construct an array with the same size and values in @a sa. valarray(const slice_array<_Tp>&); /// Construct an array with the same size and values in @a ga. valarray(const gslice_array<_Tp>&); /// Construct an array with the same size and values in @a ma. valarray(const mask_array<_Tp>&); /// Construct an array with the same size and values in @a ia. valarray(const indirect_array<_Tp>&); #if __cplusplus >= 201103L /// Construct an array with an initializer_list of values. valarray(initializer_list<_Tp>); #endif template valarray(const _Expr<_Dom, _Tp>& __e); ~valarray() _GLIBCXX_NOEXCEPT; // _lib.valarray.assign_ assignment: /** * @brief Assign elements to an array. * * Assign elements of array to values in @a v. * * @param __v Valarray to get values from. */ valarray<_Tp>& operator=(const valarray<_Tp>& __v); #if __cplusplus >= 201103L /** * @brief Move assign elements to an array. * * Move assign elements of array to values in @a v. * * @param __v Valarray to get values from. */ valarray<_Tp>& operator=(valarray<_Tp>&& __v) noexcept; #endif /** * @brief Assign elements to a value. * * Assign all elements of array to @a t. * * @param __t Value for elements. */ valarray<_Tp>& operator=(const _Tp& __t); /** * @brief Assign elements to an array subset. * * Assign elements of array to values in @a sa. Results are undefined * if @a sa does not have the same size as this array. * * @param __sa Array slice to get values from. */ valarray<_Tp>& operator=(const slice_array<_Tp>& __sa); /** * @brief Assign elements to an array subset. * * Assign elements of array to values in @a ga. Results are undefined * if @a ga does not have the same size as this array. * * @param __ga Array slice to get values from. */ valarray<_Tp>& operator=(const gslice_array<_Tp>& __ga); /** * @brief Assign elements to an array subset. * * Assign elements of array to values in @a ma. Results are undefined * if @a ma does not have the same size as this array. * * @param __ma Array slice to get values from. */ valarray<_Tp>& operator=(const mask_array<_Tp>& __ma); /** * @brief Assign elements to an array subset. * * Assign elements of array to values in @a ia. Results are undefined * if @a ia does not have the same size as this array. * * @param __ia Array slice to get values from. */ valarray<_Tp>& operator=(const indirect_array<_Tp>& __ia); #if __cplusplus >= 201103L /** * @brief Assign elements to an initializer_list. * * Assign elements of array to values in @a __l. Results are undefined * if @a __l does not have the same size as this array. * * @param __l initializer_list to get values from. */ valarray& operator=(initializer_list<_Tp> __l); #endif template valarray<_Tp>& operator= (const _Expr<_Dom, _Tp>&); // _lib.valarray.access_ element access: /** * Return a reference to the i'th array element. * * @param __i Index of element to return. * @return Reference to the i'th element. */ _Tp& operator[](size_t __i); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 389. Const overload of valarray::operator[] returns by value. const _Tp& operator[](size_t) const; // _lib.valarray.sub_ subset operations: /** * @brief Return an array subset. * * Returns a new valarray containing the elements of the array * indicated by the slice argument. The new valarray has the same size * as the input slice. @see slice. * * @param __s The source slice. * @return New valarray containing elements in @a __s. */ _Expr<_SClos<_ValArray, _Tp>, _Tp> operator[](slice __s) const; /** * @brief Return a reference to an array subset. * * Returns a new valarray containing the elements of the array * indicated by the slice argument. The new valarray has the same size * as the input slice. @see slice. * * @param __s The source slice. * @return New valarray containing elements in @a __s. */ slice_array<_Tp> operator[](slice __s); /** * @brief Return an array subset. * * Returns a slice_array referencing the elements of the array * indicated by the slice argument. @see gslice. * * @param __s The source slice. * @return Slice_array referencing elements indicated by @a __s. */ _Expr<_GClos<_ValArray, _Tp>, _Tp> operator[](const gslice& __s) const; /** * @brief Return a reference to an array subset. * * Returns a new valarray containing the elements of the array * indicated by the gslice argument. The new valarray has * the same size as the input gslice. @see gslice. * * @param __s The source gslice. * @return New valarray containing elements in @a __s. */ gslice_array<_Tp> operator[](const gslice& __s); /** * @brief Return an array subset. * * Returns a new valarray containing the elements of the array * indicated by the argument. The input is a valarray of bool which * represents a bitmask indicating which elements should be copied into * the new valarray. Each element of the array is added to the return * valarray if the corresponding element of the argument is true. * * @param __m The valarray bitmask. * @return New valarray containing elements indicated by @a __m. */ valarray<_Tp> operator[](const valarray& __m) const; /** * @brief Return a reference to an array subset. * * Returns a new mask_array referencing the elements of the array * indicated by the argument. The input is a valarray of bool which * represents a bitmask indicating which elements are part of the * subset. Elements of the array are part of the subset if the * corresponding element of the argument is true. * * @param __m The valarray bitmask. * @return New valarray containing elements indicated by @a __m. */ mask_array<_Tp> operator[](const valarray& __m); /** * @brief Return an array subset. * * Returns a new valarray containing the elements of the array * indicated by the argument. The elements in the argument are * interpreted as the indices of elements of this valarray to copy to * the return valarray. * * @param __i The valarray element index list. * @return New valarray containing elements in @a __s. */ _Expr<_IClos<_ValArray, _Tp>, _Tp> operator[](const valarray& __i) const; /** * @brief Return a reference to an array subset. * * Returns an indirect_array referencing the elements of the array * indicated by the argument. The elements in the argument are * interpreted as the indices of elements of this valarray to include * in the subset. The returned indirect_array refers to these * elements. * * @param __i The valarray element index list. * @return Indirect_array referencing elements in @a __i. */ indirect_array<_Tp> operator[](const valarray& __i); // _lib.valarray.unary_ unary operators: /// Return a new valarray by applying unary + to each element. typename _UnaryOp<__unary_plus>::_Rt operator+() const; /// Return a new valarray by applying unary - to each element. typename _UnaryOp<__negate>::_Rt operator-() const; /// Return a new valarray by applying unary ~ to each element. typename _UnaryOp<__bitwise_not>::_Rt operator~() const; /// Return a new valarray by applying unary ! to each element. typename _UnaryOp<__logical_not>::_Rt operator!() const; // _lib.valarray.cassign_ computed assignment: /// Multiply each element of array by @a t. valarray<_Tp>& operator*=(const _Tp&); /// Divide each element of array by @a t. valarray<_Tp>& operator/=(const _Tp&); /// Set each element e of array to e % @a t. valarray<_Tp>& operator%=(const _Tp&); /// Add @a t to each element of array. valarray<_Tp>& operator+=(const _Tp&); /// Subtract @a t to each element of array. valarray<_Tp>& operator-=(const _Tp&); /// Set each element e of array to e ^ @a t. valarray<_Tp>& operator^=(const _Tp&); /// Set each element e of array to e & @a t. valarray<_Tp>& operator&=(const _Tp&); /// Set each element e of array to e | @a t. valarray<_Tp>& operator|=(const _Tp&); /// Left shift each element e of array by @a t bits. valarray<_Tp>& operator<<=(const _Tp&); /// Right shift each element e of array by @a t bits. valarray<_Tp>& operator>>=(const _Tp&); /// Multiply elements of array by corresponding elements of @a v. valarray<_Tp>& operator*=(const valarray<_Tp>&); /// Divide elements of array by corresponding elements of @a v. valarray<_Tp>& operator/=(const valarray<_Tp>&); /// Modulo elements of array by corresponding elements of @a v. valarray<_Tp>& operator%=(const valarray<_Tp>&); /// Add corresponding elements of @a v to elements of array. valarray<_Tp>& operator+=(const valarray<_Tp>&); /// Subtract corresponding elements of @a v from elements of array. valarray<_Tp>& operator-=(const valarray<_Tp>&); /// Logical xor corresponding elements of @a v with elements of array. valarray<_Tp>& operator^=(const valarray<_Tp>&); /// Logical or corresponding elements of @a v with elements of array. valarray<_Tp>& operator|=(const valarray<_Tp>&); /// Logical and corresponding elements of @a v with elements of array. valarray<_Tp>& operator&=(const valarray<_Tp>&); /// Left shift elements of array by corresponding elements of @a v. valarray<_Tp>& operator<<=(const valarray<_Tp>&); /// Right shift elements of array by corresponding elements of @a v. valarray<_Tp>& operator>>=(const valarray<_Tp>&); template valarray<_Tp>& operator*=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator/=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator%=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator+=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator-=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator^=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator|=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator&=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator<<=(const _Expr<_Dom, _Tp>&); template valarray<_Tp>& operator>>=(const _Expr<_Dom, _Tp>&); // _lib.valarray.members_ member functions: #if __cplusplus >= 201103L /// Swap. void swap(valarray<_Tp>& __v) noexcept; #endif /// Return the number of elements in array. size_t size() const; /** * @brief Return the sum of all elements in the array. * * Accumulates the sum of all elements into a Tp using +=. The order * of adding the elements is unspecified. */ _Tp sum() const; /// Return the minimum element using operator<(). _Tp min() const; /// Return the maximum element using operator<(). _Tp max() const; /** * @brief Return a shifted array. * * A new valarray is constructed as a copy of this array with elements * in shifted positions. For an element with index i, the new position * is i - n. The new valarray has the same size as the current one. * New elements without a value are set to 0. Elements whose new * position is outside the bounds of the array are discarded. * * Positive arguments shift toward index 0, discarding elements [0, n). * Negative arguments discard elements from the top of the array. * * @param __n Number of element positions to shift. * @return New valarray with elements in shifted positions. */ valarray<_Tp> shift (int __n) const; /** * @brief Return a rotated array. * * A new valarray is constructed as a copy of this array with elements * in shifted positions. For an element with index i, the new position * is (i - n) % size(). The new valarray has the same size as the * current one. Elements that are shifted beyond the array bounds are * shifted into the other end of the array. No elements are lost. * * Positive arguments shift toward index 0, wrapping around the top. * Negative arguments shift towards the top, wrapping around to 0. * * @param __n Number of element positions to rotate. * @return New valarray with elements in shifted positions. */ valarray<_Tp> cshift(int __n) const; /** * @brief Apply a function to the array. * * Returns a new valarray with elements assigned to the result of * applying func to the corresponding element of this array. The new * array has the same size as this one. * * @param func Function of Tp returning Tp to apply. * @return New valarray with transformed elements. */ _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(_Tp)) const; /** * @brief Apply a function to the array. * * Returns a new valarray with elements assigned to the result of * applying func to the corresponding element of this array. The new * array has the same size as this one. * * @param func Function of const Tp& returning Tp to apply. * @return New valarray with transformed elements. */ _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(const _Tp&)) const; /** * @brief Resize array. * * Resize this array to @a size and set all elements to @a c. All * references and iterators are invalidated. * * @param __size New array size. * @param __c New value for all elements. */ void resize(size_t __size, _Tp __c = _Tp()); private: size_t _M_size; _Tp* __restrict__ _M_data; friend class _Array<_Tp>; }; #if __cpp_deduction_guides >= 201606 template valarray(const _Tp(&)[_Nm], size_t) -> valarray<_Tp>; #endif template inline const _Tp& valarray<_Tp>::operator[](size_t __i) const { __glibcxx_requires_subscript(__i); return _M_data[__i]; } template inline _Tp& valarray<_Tp>::operator[](size_t __i) { __glibcxx_requires_subscript(__i); return _M_data[__i]; } // @} group numeric_arrays _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup numeric_arrays * @{ */ template inline valarray<_Tp>::valarray() : _M_size(0), _M_data(0) {} template inline valarray<_Tp>::valarray(size_t __n) : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) { std::__valarray_default_construct(_M_data, _M_data + __n); } template inline valarray<_Tp>::valarray(const _Tp& __t, size_t __n) : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) { std::__valarray_fill_construct(_M_data, _M_data + __n, __t); } template inline valarray<_Tp>::valarray(const _Tp* __restrict__ __p, size_t __n) : _M_size(__n), _M_data(__valarray_get_storage<_Tp>(__n)) { __glibcxx_assert(__p != 0 || __n == 0); std::__valarray_copy_construct(__p, __p + __n, _M_data); } template inline valarray<_Tp>::valarray(const valarray<_Tp>& __v) : _M_size(__v._M_size), _M_data(__valarray_get_storage<_Tp>(__v._M_size)) { std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size, _M_data); } #if __cplusplus >= 201103L template inline valarray<_Tp>::valarray(valarray<_Tp>&& __v) noexcept : _M_size(__v._M_size), _M_data(__v._M_data) { __v._M_size = 0; __v._M_data = 0; } #endif template inline valarray<_Tp>::valarray(const slice_array<_Tp>& __sa) : _M_size(__sa._M_sz), _M_data(__valarray_get_storage<_Tp>(__sa._M_sz)) { std::__valarray_copy_construct (__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data)); } template inline valarray<_Tp>::valarray(const gslice_array<_Tp>& __ga) : _M_size(__ga._M_index.size()), _M_data(__valarray_get_storage<_Tp>(_M_size)) { std::__valarray_copy_construct (__ga._M_array, _Array(__ga._M_index), _Array<_Tp>(_M_data), _M_size); } template inline valarray<_Tp>::valarray(const mask_array<_Tp>& __ma) : _M_size(__ma._M_sz), _M_data(__valarray_get_storage<_Tp>(__ma._M_sz)) { std::__valarray_copy_construct (__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size); } template inline valarray<_Tp>::valarray(const indirect_array<_Tp>& __ia) : _M_size(__ia._M_sz), _M_data(__valarray_get_storage<_Tp>(__ia._M_sz)) { std::__valarray_copy_construct (__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size); } #if __cplusplus >= 201103L template inline valarray<_Tp>::valarray(initializer_list<_Tp> __l) : _M_size(__l.size()), _M_data(__valarray_get_storage<_Tp>(__l.size())) { std::__valarray_copy_construct(__l.begin(), __l.end(), _M_data); } #endif template template inline valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e) : _M_size(__e.size()), _M_data(__valarray_get_storage<_Tp>(_M_size)) { std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); } template inline valarray<_Tp>::~valarray() _GLIBCXX_NOEXCEPT { std::__valarray_destroy_elements(_M_data, _M_data + _M_size); std::__valarray_release_memory(_M_data); } template inline valarray<_Tp>& valarray<_Tp>::operator=(const valarray<_Tp>& __v) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 630. arrays of valarray. if (_M_size == __v._M_size) std::__valarray_copy(__v._M_data, _M_size, _M_data); else { if (_M_data) { std::__valarray_destroy_elements(_M_data, _M_data + _M_size); std::__valarray_release_memory(_M_data); } _M_size = __v._M_size; _M_data = __valarray_get_storage<_Tp>(_M_size); std::__valarray_copy_construct(__v._M_data, __v._M_data + _M_size, _M_data); } return *this; } #if __cplusplus >= 201103L template inline valarray<_Tp>& valarray<_Tp>::operator=(valarray<_Tp>&& __v) noexcept { if (_M_data) { std::__valarray_destroy_elements(_M_data, _M_data + _M_size); std::__valarray_release_memory(_M_data); } _M_size = __v._M_size; _M_data = __v._M_data; __v._M_size = 0; __v._M_data = 0; return *this; } template inline valarray<_Tp>& valarray<_Tp>::operator=(initializer_list<_Tp> __l) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 630. arrays of valarray. if (_M_size == __l.size()) std::__valarray_copy(__l.begin(), __l.size(), _M_data); else { if (_M_data) { std::__valarray_destroy_elements(_M_data, _M_data + _M_size); std::__valarray_release_memory(_M_data); } _M_size = __l.size(); _M_data = __valarray_get_storage<_Tp>(_M_size); std::__valarray_copy_construct(__l.begin(), __l.begin() + _M_size, _M_data); } return *this; } #endif template inline valarray<_Tp>& valarray<_Tp>::operator=(const _Tp& __t) { std::__valarray_fill(_M_data, _M_size, __t); return *this; } template inline valarray<_Tp>& valarray<_Tp>::operator=(const slice_array<_Tp>& __sa) { __glibcxx_assert(_M_size == __sa._M_sz); std::__valarray_copy(__sa._M_array, __sa._M_sz, __sa._M_stride, _Array<_Tp>(_M_data)); return *this; } template inline valarray<_Tp>& valarray<_Tp>::operator=(const gslice_array<_Tp>& __ga) { __glibcxx_assert(_M_size == __ga._M_index.size()); std::__valarray_copy(__ga._M_array, _Array(__ga._M_index), _Array<_Tp>(_M_data), _M_size); return *this; } template inline valarray<_Tp>& valarray<_Tp>::operator=(const mask_array<_Tp>& __ma) { __glibcxx_assert(_M_size == __ma._M_sz); std::__valarray_copy(__ma._M_array, __ma._M_mask, _Array<_Tp>(_M_data), _M_size); return *this; } template inline valarray<_Tp>& valarray<_Tp>::operator=(const indirect_array<_Tp>& __ia) { __glibcxx_assert(_M_size == __ia._M_sz); std::__valarray_copy(__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size); return *this; } template template inline valarray<_Tp>& valarray<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 630. arrays of valarray. if (_M_size == __e.size()) std::__valarray_copy(__e, _M_size, _Array<_Tp>(_M_data)); else { if (_M_data) { std::__valarray_destroy_elements(_M_data, _M_data + _M_size); std::__valarray_release_memory(_M_data); } _M_size = __e.size(); _M_data = __valarray_get_storage<_Tp>(_M_size); std::__valarray_copy_construct(__e, _M_size, _Array<_Tp>(_M_data)); } return *this; } template inline _Expr<_SClos<_ValArray,_Tp>, _Tp> valarray<_Tp>::operator[](slice __s) const { typedef _SClos<_ValArray,_Tp> _Closure; return _Expr<_Closure, _Tp>(_Closure (_Array<_Tp>(_M_data), __s)); } template inline slice_array<_Tp> valarray<_Tp>::operator[](slice __s) { return slice_array<_Tp>(_Array<_Tp>(_M_data), __s); } template inline _Expr<_GClos<_ValArray,_Tp>, _Tp> valarray<_Tp>::operator[](const gslice& __gs) const { typedef _GClos<_ValArray,_Tp> _Closure; return _Expr<_Closure, _Tp> (_Closure(_Array<_Tp>(_M_data), __gs._M_index->_M_index)); } template inline gslice_array<_Tp> valarray<_Tp>::operator[](const gslice& __gs) { return gslice_array<_Tp> (_Array<_Tp>(_M_data), __gs._M_index->_M_index); } template inline valarray<_Tp> valarray<_Tp>::operator[](const valarray& __m) const { size_t __s = 0; size_t __e = __m.size(); for (size_t __i=0; __i<__e; ++__i) if (__m[__i]) ++__s; return valarray<_Tp>(mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array (__m))); } template inline mask_array<_Tp> valarray<_Tp>::operator[](const valarray& __m) { size_t __s = 0; size_t __e = __m.size(); for (size_t __i=0; __i<__e; ++__i) if (__m[__i]) ++__s; return mask_array<_Tp>(_Array<_Tp>(_M_data), __s, _Array(__m)); } template inline _Expr<_IClos<_ValArray,_Tp>, _Tp> valarray<_Tp>::operator[](const valarray& __i) const { typedef _IClos<_ValArray,_Tp> _Closure; return _Expr<_Closure, _Tp>(_Closure(*this, __i)); } template inline indirect_array<_Tp> valarray<_Tp>::operator[](const valarray& __i) { return indirect_array<_Tp>(_Array<_Tp>(_M_data), __i.size(), _Array(__i)); } #if __cplusplus >= 201103L template inline void valarray<_Tp>::swap(valarray<_Tp>& __v) noexcept { std::swap(_M_size, __v._M_size); std::swap(_M_data, __v._M_data); } #endif template inline size_t valarray<_Tp>::size() const { return _M_size; } template inline _Tp valarray<_Tp>::sum() const { __glibcxx_assert(_M_size > 0); return std::__valarray_sum(_M_data, _M_data + _M_size); } template inline valarray<_Tp> valarray<_Tp>::shift(int __n) const { valarray<_Tp> __ret; if (_M_size == 0) return __ret; _Tp* __restrict__ __tmp_M_data = std::__valarray_get_storage<_Tp>(_M_size); if (__n == 0) std::__valarray_copy_construct(_M_data, _M_data + _M_size, __tmp_M_data); else if (__n > 0) // shift left { if (size_t(__n) > _M_size) __n = int(_M_size); std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size, __tmp_M_data); std::__valarray_default_construct(__tmp_M_data + _M_size - __n, __tmp_M_data + _M_size); } else // shift right { if (-size_t(__n) > _M_size) __n = -int(_M_size); std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n, __tmp_M_data - __n); std::__valarray_default_construct(__tmp_M_data, __tmp_M_data - __n); } __ret._M_size = _M_size; __ret._M_data = __tmp_M_data; return __ret; } template inline valarray<_Tp> valarray<_Tp>::cshift(int __n) const { valarray<_Tp> __ret; if (_M_size == 0) return __ret; _Tp* __restrict__ __tmp_M_data = std::__valarray_get_storage<_Tp>(_M_size); if (__n == 0) std::__valarray_copy_construct(_M_data, _M_data + _M_size, __tmp_M_data); else if (__n > 0) // cshift left { if (size_t(__n) > _M_size) __n = int(__n % _M_size); std::__valarray_copy_construct(_M_data, _M_data + __n, __tmp_M_data + _M_size - __n); std::__valarray_copy_construct(_M_data + __n, _M_data + _M_size, __tmp_M_data); } else // cshift right { if (-size_t(__n) > _M_size) __n = -int(-size_t(__n) % _M_size); std::__valarray_copy_construct(_M_data + _M_size + __n, _M_data + _M_size, __tmp_M_data); std::__valarray_copy_construct(_M_data, _M_data + _M_size + __n, __tmp_M_data - __n); } __ret._M_size = _M_size; __ret._M_data = __tmp_M_data; return __ret; } template inline void valarray<_Tp>::resize(size_t __n, _Tp __c) { // This complication is so to make valarray > work // even though it is not required by the standard. Nobody should // be saying valarray > anyway. See the specs. std::__valarray_destroy_elements(_M_data, _M_data + _M_size); if (_M_size != __n) { std::__valarray_release_memory(_M_data); _M_size = __n; _M_data = __valarray_get_storage<_Tp>(__n); } std::__valarray_fill_construct(_M_data, _M_data + __n, __c); } template inline _Tp valarray<_Tp>::min() const { __glibcxx_assert(_M_size > 0); return *std::min_element(_M_data, _M_data + _M_size); } template inline _Tp valarray<_Tp>::max() const { __glibcxx_assert(_M_size > 0); return *std::max_element(_M_data, _M_data + _M_size); } template inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> valarray<_Tp>::apply(_Tp func(_Tp)) const { typedef _ValFunClos<_ValArray, _Tp> _Closure; return _Expr<_Closure, _Tp>(_Closure(*this, func)); } template inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> valarray<_Tp>::apply(_Tp func(const _Tp &)) const { typedef _RefFunClos<_ValArray, _Tp> _Closure; return _Expr<_Closure, _Tp>(_Closure(*this, func)); } #define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \ template \ inline typename valarray<_Tp>::template _UnaryOp<_Name>::_Rt \ valarray<_Tp>::operator _Op() const \ { \ typedef _UnClos<_Name, _ValArray, _Tp> _Closure; \ typedef typename __fun<_Name, _Tp>::result_type _Rt; \ return _Expr<_Closure, _Rt>(_Closure(*this)); \ } _DEFINE_VALARRAY_UNARY_OPERATOR(+, __unary_plus) _DEFINE_VALARRAY_UNARY_OPERATOR(-, __negate) _DEFINE_VALARRAY_UNARY_OPERATOR(~, __bitwise_not) _DEFINE_VALARRAY_UNARY_OPERATOR (!, __logical_not) #undef _DEFINE_VALARRAY_UNARY_OPERATOR #define _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(_Op, _Name) \ template \ inline valarray<_Tp>& \ valarray<_Tp>::operator _Op##=(const _Tp &__t) \ { \ _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, __t); \ return *this; \ } \ \ template \ inline valarray<_Tp>& \ valarray<_Tp>::operator _Op##=(const valarray<_Tp> &__v) \ { \ __glibcxx_assert(_M_size == __v._M_size); \ _Array_augmented_##_Name(_Array<_Tp>(_M_data), _M_size, \ _Array<_Tp>(__v._M_data)); \ return *this; \ } _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(+, __plus) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(-, __minus) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(*, __multiplies) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(/, __divides) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(%, __modulus) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(&, __bitwise_and) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(|, __bitwise_or) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(<<, __shift_left) _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT(>>, __shift_right) #undef _DEFINE_VALARRAY_AUGMENTED_ASSIGNMENT #define _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(_Op, _Name) \ template template \ inline valarray<_Tp>& \ valarray<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) \ { \ _Array_augmented_##_Name(_Array<_Tp>(_M_data), __e, _M_size); \ return *this; \ } _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(+, __plus) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(-, __minus) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(*, __multiplies) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(/, __divides) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(%, __modulus) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(^, __bitwise_xor) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(&, __bitwise_and) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(|, __bitwise_or) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(<<, __shift_left) _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT(>>, __shift_right) #undef _DEFINE_VALARRAY_EXPR_AUGMENTED_ASSIGNMENT #define _DEFINE_BINARY_OPERATOR(_Op, _Name) \ template \ inline _Expr<_BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp>, \ typename __fun<_Name, _Tp>::result_type> \ operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ { \ __glibcxx_assert(__v.size() == __w.size()); \ typedef _BinClos<_Name, _ValArray, _ValArray, _Tp, _Tp> _Closure; \ typedef typename __fun<_Name, _Tp>::result_type _Rt; \ return _Expr<_Closure, _Rt>(_Closure(__v, __w)); \ } \ \ template \ inline _Expr<_BinClos<_Name, _ValArray,_Constant, _Tp, _Tp>, \ typename __fun<_Name, _Tp>::result_type> \ operator _Op(const valarray<_Tp>& __v, const _Tp& __t) \ { \ typedef _BinClos<_Name, _ValArray, _Constant, _Tp, _Tp> _Closure; \ typedef typename __fun<_Name, _Tp>::result_type _Rt; \ return _Expr<_Closure, _Rt>(_Closure(__v, __t)); \ } \ \ template \ inline _Expr<_BinClos<_Name, _Constant, _ValArray, _Tp, _Tp>, \ typename __fun<_Name, _Tp>::result_type> \ operator _Op(const _Tp& __t, const valarray<_Tp>& __v) \ { \ typedef _BinClos<_Name, _Constant, _ValArray, _Tp, _Tp> _Closure; \ typedef typename __fun<_Name, _Tp>::result_type _Rt; \ return _Expr<_Closure, _Rt>(_Closure(__t, __v)); \ } _DEFINE_BINARY_OPERATOR(+, __plus) _DEFINE_BINARY_OPERATOR(-, __minus) _DEFINE_BINARY_OPERATOR(*, __multiplies) _DEFINE_BINARY_OPERATOR(/, __divides) _DEFINE_BINARY_OPERATOR(%, __modulus) _DEFINE_BINARY_OPERATOR(^, __bitwise_xor) _DEFINE_BINARY_OPERATOR(&, __bitwise_and) _DEFINE_BINARY_OPERATOR(|, __bitwise_or) _DEFINE_BINARY_OPERATOR(<<, __shift_left) _DEFINE_BINARY_OPERATOR(>>, __shift_right) _DEFINE_BINARY_OPERATOR(&&, __logical_and) _DEFINE_BINARY_OPERATOR(||, __logical_or) _DEFINE_BINARY_OPERATOR(==, __equal_to) _DEFINE_BINARY_OPERATOR(!=, __not_equal_to) _DEFINE_BINARY_OPERATOR(<, __less) _DEFINE_BINARY_OPERATOR(>, __greater) _DEFINE_BINARY_OPERATOR(<=, __less_equal) _DEFINE_BINARY_OPERATOR(>=, __greater_equal) #undef _DEFINE_BINARY_OPERATOR #if __cplusplus >= 201103L /** * @brief Return an iterator pointing to the first element of * the valarray. * @param __va valarray. */ template inline _Tp* begin(valarray<_Tp>& __va) { return std::__addressof(__va[0]); } /** * @brief Return an iterator pointing to the first element of * the const valarray. * @param __va valarray. */ template inline const _Tp* begin(const valarray<_Tp>& __va) { return std::__addressof(__va[0]); } /** * @brief Return an iterator pointing to one past the last element of * the valarray. * @param __va valarray. */ template inline _Tp* end(valarray<_Tp>& __va) { return std::__addressof(__va[0]) + __va.size(); } /** * @brief Return an iterator pointing to one past the last element of * the const valarray. * @param __va valarray. */ template inline const _Tp* end(const valarray<_Tp>& __va) { return std::__addressof(__va[0]) + __va.size(); } #endif // C++11 // @} group numeric_arrays _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _GLIBCXX_VALARRAY */ 8/profile/set000064400000002336152526447520007111 0ustar00// Profiling set/multiset implementation -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/set * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_SET #define _GLIBCXX_PROFILE_SET 1 #include #include #include #endif 8/profile/unordered_map000064400000042210152526447520011135 0ustar00// Profiling unordered_map/unordered_multimap implementation -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/unordered_map * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_UNORDERED_MAP #define _GLIBCXX_PROFILE_UNORDERED_MAP 1 #if __cplusplus < 201103L # include #else # include #include #include #define _GLIBCXX_BASE unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc> #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::unordered_map wrapper with performance instrumentation. template, typename _Pred = std::equal_to<_Key>, typename _Alloc = std::allocator > > class unordered_map : public _GLIBCXX_STD_BASE, public _Unordered_profile, true> { typedef typename _GLIBCXX_STD_BASE _Base; _Base& _M_base() noexcept { return *this; } const _Base& _M_base() const noexcept { return *this; } public: typedef typename _Base::size_type size_type; typedef typename _Base::hasher hasher; typedef typename _Base::key_equal key_equal; typedef typename _Base::allocator_type allocator_type; typedef typename _Base::key_type key_type; typedef typename _Base::value_type value_type; typedef typename _Base::difference_type difference_type; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef typename _Base::mapped_type mapped_type; typedef typename _Base::iterator iterator; typedef typename _Base::const_iterator const_iterator; unordered_map() = default; explicit unordered_map(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__n, __hf, __eql, __a) { } template unordered_map(_InputIterator __f, _InputIterator __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__f, __l, __n, __hf, __eql, __a) { } unordered_map(const unordered_map&) = default; unordered_map(const _Base& __x) : _Base(__x) { } unordered_map(unordered_map&&) = default; explicit unordered_map(const allocator_type& __a) : _Base(__a) { } unordered_map(const unordered_map& __umap, const allocator_type& __a) : _Base(__umap, __a) { } unordered_map(unordered_map&& __umap, const allocator_type& __a) : _Base(std::move(__umap._M_base()), __a) { } unordered_map(initializer_list __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } unordered_map(size_type __n, const allocator_type& __a) : unordered_map(__n, hasher(), key_equal(), __a) { } unordered_map(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__n, __hf, key_equal(), __a) { } template unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) { } template unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__first, __last, __n, __hf, key_equal(), __a) { } unordered_map(initializer_list __l, size_type __n, const allocator_type& __a) : unordered_map(__l, __n, hasher(), key_equal(), __a) { } unordered_map(initializer_list __l, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__l, __n, __hf, key_equal(), __a) { } unordered_map& operator=(const unordered_map&) = default; unordered_map& operator=(unordered_map&&) = default; unordered_map& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } void clear() noexcept { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } template std::pair emplace(_Args&&... __args) { size_type __old_size = _Base::bucket_count(); std::pair __res = _Base::emplace(std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } template iterator emplace_hint(const_iterator __it, _Args&&... __args) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } void insert(std::initializer_list __l) { size_type __old_size = _Base::bucket_count(); _Base::insert(__l); this->_M_profile_resize(__old_size); } std::pair insert(const value_type& __obj) { size_type __old_size = _Base::bucket_count(); std::pair __res = _Base::insert(__obj); this->_M_profile_resize(__old_size); return __res; } iterator insert(const_iterator __iter, const value_type& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, __v); this->_M_profile_resize(__old_size); return __res; } template::value>::type> std::pair insert(_Pair&& __obj) { size_type __old_size = _Base::bucket_count(); std::pair __res = _Base::insert(std::forward<_Pair>(__obj)); this->_M_profile_resize(__old_size); return __res; } template::value>::type> iterator insert(const_iterator __iter, _Pair&& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v)); this->_M_profile_resize(__old_size); return __res; } template void insert(_InputIter __first, _InputIter __last) { size_type __old_size = _Base::bucket_count(); _Base::insert(__first, __last); this->_M_profile_resize(__old_size); } // operator[] mapped_type& operator[](const _Key& __k) { size_type __old_size = _Base::bucket_count(); mapped_type& __res = _M_base()[__k]; this->_M_profile_resize(__old_size); return __res; } mapped_type& operator[](_Key&& __k) { size_type __old_size = _Base::bucket_count(); mapped_type& __res = _M_base()[std::move(__k)]; this->_M_profile_resize(__old_size); return __res; } void swap(unordered_map& __x) noexcept( noexcept(__x._M_base().swap(__x)) ) { _Base::swap(__x._M_base()); this->_M_swap(__x); } void rehash(size_type __n) { size_type __old_size = _Base::bucket_count(); _Base::rehash(__n); this->_M_profile_resize(__old_size); } }; template inline void swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template inline bool operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { return static_cast(__x) == __y; } template inline bool operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } #undef _GLIBCXX_BASE #undef _GLIBCXX_STD_BASE #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc> #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE /// Class std::unordered_multimap wrapper with performance instrumentation. template, typename _Pred = std::equal_to<_Key>, typename _Alloc = std::allocator > > class unordered_multimap : public _GLIBCXX_STD_BASE, public _Unordered_profile, false> { typedef typename _GLIBCXX_STD_BASE _Base; _Base& _M_base() noexcept { return *this; } const _Base& _M_base() const noexcept { return *this; } public: typedef typename _Base::size_type size_type; typedef typename _Base::hasher hasher; typedef typename _Base::key_equal key_equal; typedef typename _Base::allocator_type allocator_type; typedef typename _Base::key_type key_type; typedef typename _Base::value_type value_type; typedef typename _Base::difference_type difference_type; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef typename _Base::iterator iterator; typedef typename _Base::const_iterator const_iterator; unordered_multimap() = default; explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__n, __hf, __eql, __a) { } template unordered_multimap(_InputIterator __f, _InputIterator __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__f, __l, __n, __hf, __eql, __a) { } unordered_multimap(const unordered_multimap&) = default; unordered_multimap(const _Base& __x) : _Base(__x) { } unordered_multimap(unordered_multimap&&) = default; explicit unordered_multimap(const allocator_type& __a) : _Base(__a) { } unordered_multimap(const unordered_multimap& __ummap, const allocator_type& __a) : _Base(__ummap._M_base(), __a) { } unordered_multimap(unordered_multimap&& __ummap, const allocator_type& __a) : _Base(std::move(__ummap._M_base()), __a) { } unordered_multimap(initializer_list __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } unordered_multimap(size_type __n, const allocator_type& __a) : unordered_multimap(__n, hasher(), key_equal(), __a) { } unordered_multimap(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__n, __hf, key_equal(), __a) { } template unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) { } template unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) { } unordered_multimap(initializer_list __l, size_type __n, const allocator_type& __a) : unordered_multimap(__l, __n, hasher(), key_equal(), __a) { } unordered_multimap(initializer_list __l, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__l, __n, __hf, key_equal(), __a) { } unordered_multimap& operator=(const unordered_multimap&) = default; unordered_multimap& operator=(unordered_multimap&&) = default; unordered_multimap& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } void clear() noexcept { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } template iterator emplace(_Args&&... __args) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::emplace(std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } template iterator emplace_hint(const_iterator __it, _Args&&... __args) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } void insert(std::initializer_list __l) { size_type __old_size = _Base::bucket_count(); _Base::insert(__l); this->_M_profile_resize(__old_size); } iterator insert(const value_type& __obj) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__obj); this->_M_profile_resize(__old_size); return __res; } iterator insert(const_iterator __iter, const value_type& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, __v); this->_M_profile_resize(__old_size); return __res; } template::value>::type> iterator insert(_Pair&& __obj) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(std::forward<_Pair>(__obj)); this->_M_profile_resize(__old_size); return __res; } template::value>::type> iterator insert(const_iterator __iter, _Pair&& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v)); this->_M_profile_resize(__old_size); return __res; } template void insert(_InputIter __first, _InputIter __last) { size_type __old_size = _Base::bucket_count(); _Base::insert(__first, __last); this->_M_profile_resize(__old_size); } void swap(unordered_multimap& __x) noexcept( noexcept(__x._M_base().swap(__x)) ) { _Base::swap(__x._M_base()); this->_M_swap(__x); } void rehash(size_type __n) { size_type __old_size = _Base::bucket_count(); _Base::rehash(__n); this->_M_profile_resize(__old_size); } }; template inline void swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template inline bool operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { return static_cast(__x) == __y; } template inline bool operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } } // namespace __profile } // namespace std #undef _GLIBCXX_BASE #undef _GLIBCXX_STD_BASE #endif // C++11 #endif 8/profile/multimap.h000064400000045606152526447520010403 0ustar00// Profiling multimap implementation -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file profile/multimap.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_MULTIMAP_H #define _GLIBCXX_PROFILE_MULTIMAP_H 1 #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::multimap wrapper with performance instrumentation. template, typename _Allocator = std::allocator > > class multimap : public _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator>, public _Ordered_profile > { typedef _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator> _Base; typedef typename _Base::iterator _Base_iterator; typedef typename _Base::const_iterator _Base_const_iterator; public: // types: typedef _Key key_type; typedef _Tp mapped_type; typedef std::pair value_type; typedef _Compare key_compare; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __iterator_tracker<_Base_iterator, multimap> iterator; typedef __iterator_tracker<_Base_const_iterator, multimap> const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef typename _Base::size_type size_type; typedef typename _Base::difference_type difference_type; // 23.3.1.1 construct/copy/destroy: #if __cplusplus < 201103L multimap() : _Base() { } multimap(const multimap& __x) : _Base(__x) { } ~multimap() { } #else multimap() = default; multimap(const multimap&) = default; multimap(multimap&&) = default; ~multimap() = default; #endif explicit multimap(const _Compare& __comp, const _Allocator& __a = _Allocator()) : _Base(__comp, __a) { } #if __cplusplus >= 201103L template> #else template #endif multimap(_InputIterator __first, _InputIterator __last, const _Compare& __comp = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__first, __last, __comp, __a) { } #if __cplusplus >= 201103L multimap(initializer_list __l, const _Compare& __c = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__l, __c, __a) { } explicit multimap(const _Allocator& __a) : _Base(__a) { } multimap(const multimap& __x, const _Allocator& __a) : _Base(__x, __a) { } multimap(multimap&& __x, const _Allocator& __a) noexcept( noexcept(_Base(std::move(__x), __a)) ) : _Base(std::move(__x), __a) { } multimap(initializer_list __l, const _Allocator& __a) : _Base(__l, __a) { } template multimap(_InputIterator __first, _InputIterator __last, const _Allocator& __a) : _Base(__first, __last, __a) { } #endif multimap(const _Base& __x) : _Base(__x) { } #if __cplusplus < 201103L multimap& operator=(const multimap& __x) { this->_M_profile_destruct(); _M_base() = __x; this->_M_profile_construct(); return *this; } #else multimap& operator=(const multimap&) = default; multimap& operator=(multimap&&) = default; multimap& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } #endif // iterators iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::begin(), this); } iterator end() _GLIBCXX_NOEXCEPT { return iterator(_Base::end(), this); } const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::end(), this); } #if __cplusplus >= 201103L const_iterator cbegin() const noexcept { return const_iterator(_Base::cbegin(), this); } const_iterator cend() const noexcept { return const_iterator(_Base::cend(), this); } #endif reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L const_reverse_iterator crbegin() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cend()); } const_reverse_iterator crend() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cbegin()); } #endif // modifiers: #if __cplusplus >= 201103L template iterator emplace(_Args&&... __args) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::emplace(std::forward<_Args>(__args)...), this); } template iterator emplace_hint(const_iterator __pos, _Args&&... __args) { auto size_before = this->size(); auto __res = _Base::emplace_hint(__pos.base(), std::forward<_Args>(__args)...); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif iterator insert(const value_type& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::insert(__x), this); } #if __cplusplus >= 201103L template::value>::type> iterator insert(_Pair&& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::insert(std::forward<_Pair>(__x)), this); } #endif #if __cplusplus >= 201103L void insert(std::initializer_list __list) { insert(__list.begin(), __list.end()); } #endif iterator #if __cplusplus >= 201103L insert(const_iterator __pos, const value_type& __x) #else insert(iterator __pos, const value_type& __x) #endif { size_type size_before = this->size(); _Base_iterator __res = _Base::insert(__pos.base(), __x); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #if __cplusplus >= 201103L template::value>::type> iterator insert(const_iterator __pos, _Pair&& __x) { size_type size_before = this->size(); auto __res = _Base::insert(__pos.base(), std::forward<_Pair>(__x)); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif template void insert(_InputIterator __first, _InputIterator __last) { for (; __first != __last; ++__first) insert(*__first); } #if __cplusplus >= 201103L iterator erase(const_iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::erase(__pos.base()), this); } iterator erase(iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::erase(__pos.base()), this); } #else void erase(iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); _Base::erase(__pos.base()); } #endif size_type erase(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return _Base::erase(__x); } #if __cplusplus >= 201103L iterator erase(const_iterator __first, const_iterator __last) { if (__first != __last) { iterator __ret; for (; __first != __last;) __ret = erase(__first++); return __ret; } else return iterator(_Base::erase(__first.base(), __last.base()), this); } #else void erase(iterator __first, iterator __last) { for (; __first != __last;) erase(__first++); } #endif void swap(multimap& __x) _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) { std::swap(this->_M_map2umap_info, __x._M_map2umap_info); _Base::swap(__x); } void clear() _GLIBCXX_NOEXCEPT { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } // 23.3.1.3 multimap operations: iterator find(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return iterator(_Base::find(__x), this); } #if __cplusplus > 201103L template::type> iterator find(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } #endif const_iterator find(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return const_iterator(_Base::find(__x), this); } #if __cplusplus > 201103L template::type> const_iterator find(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } #endif size_type count(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #if __cplusplus > 201103L template::type> size_type count(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #endif iterator lower_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::lower_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator lower_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } #endif const_iterator lower_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::lower_bound(__x), this); } #if __cplusplus > 201103L template::type> const_iterator lower_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } #endif iterator upper_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::upper_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator upper_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } #endif const_iterator upper_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::upper_bound(__x), this); } #if __cplusplus > 201103L template::type> const_iterator upper_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } #endif std::pair equal_range(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_iterator, _Base_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(iterator(__base_ret.first, this), iterator(__base_ret.second, this)); } #if __cplusplus > 201103L template::type> std::pair equal_range(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } #endif std::pair equal_range(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_const_iterator, _Base_const_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(const_iterator(__base_ret.first, this), const_iterator(__base_ret.second, this)); } #if __cplusplus > 201103L template::type> std::pair equal_range(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } #endif _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } private: /** If hint is used we consider that the map and unordered_map * operations have equivalent insertion cost so we do not update metrics * about it. * Note that to find out if hint has been used is libstdc++ * implementation dependent. */ bool _M_hint_used(_Base_const_iterator __hint, _Base_iterator __res) { return (__hint == __res || (__hint == _M_base().end() && ++__res == _M_base().end()) || (__hint != _M_base().end() && (++__hint == __res || ++__res == --__hint))); } template friend bool operator==(const multimap<_K1, _T1, _C1, _A1>&, const multimap<_K1, _T1, _C1, _A1>&); template friend bool operator<(const multimap<_K1, _T1, _C1, _A1>&, const multimap<_K1, _T1, _C1, _A1>&); }; template inline bool operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() == __rhs._M_base(); } template inline bool operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() < __rhs._M_base(); } template inline bool operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) { return !(__lhs == __rhs); } template inline bool operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) { return !(__rhs < __lhs); } template inline bool operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) { return !(__lhs < __rhs); } template inline bool operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) { return __rhs < __lhs; } template inline void swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs, multimap<_Key, _Tp, _Compare, _Allocator>& __rhs) _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } } // namespace __profile } // namespace std #endif 8/profile/impl/profiler_container_size.h000064400000012433152526447520014422 0ustar00// -*- C++ -*- // // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_container_size.h * @brief Diagnostics for container sizes. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H #define _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H 1 #include #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" namespace __gnu_profile { /** @brief A container size instrumentation line in the object table. */ class __container_size_info : public __object_info_base { public: __container_size_info(__stack_t __stack) : __object_info_base(__stack), _M_init(0), _M_max(0), _M_min(0), _M_total(0), _M_item_min(0), _M_item_max(0), _M_item_total(0), _M_count(0), _M_resize(0), _M_cost(0) { } void __write(FILE* __f) const { std::fprintf(__f, "%Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu %Zu\n", _M_init, _M_count, _M_cost, _M_resize, _M_min, _M_max, _M_total, _M_item_min, _M_item_max, _M_item_total); } float __magnitude() const { return static_cast(_M_cost); } std::string __advice() const { std::stringstream __message; if (_M_init < _M_item_max) __message << "change initial container size from " << _M_init << " to " << _M_item_max; return __message.str(); } void __init(std::size_t __num) { _M_init = __num; _M_max = __num; } void __merge(const __container_size_info& __o) { __object_info_base::__merge(__o); _M_init = std::max(_M_init, __o._M_init); _M_max = std::max(_M_max, __o._M_max); _M_item_max = std::max(_M_item_max, __o._M_item_max); _M_min = std::min(_M_min, __o._M_min); _M_item_min = std::min(_M_item_min, __o._M_item_min); _M_total += __o._M_total; _M_item_total += __o._M_item_total; _M_count += __o._M_count; _M_cost += __o._M_cost; _M_resize += __o._M_resize; } // Call if a container is destructed or cleaned. void __destruct(std::size_t __num, std::size_t __inum) { _M_max = std::max(_M_max, __num); _M_item_max = std::max(_M_item_max, __inum); if (_M_min == 0) { _M_min = __num; _M_item_min = __inum; } else { _M_min = std::min(_M_min, __num); _M_item_min = std::min(_M_item_min, __inum); } _M_total += __num; _M_item_total += __inum; _M_count += 1; } // Estimate the cost of resize/rehash. float __resize_cost(std::size_t __from, std::size_t) { return __from; } // Call if container is resized. void __resize(std::size_t __from, std::size_t __to) { _M_cost += this->__resize_cost(__from, __to); _M_resize += 1; _M_max = std::max(_M_max, __to); } private: std::size_t _M_init; std::size_t _M_max; // range of # buckets std::size_t _M_min; std::size_t _M_total; std::size_t _M_item_min; // range of # items std::size_t _M_item_max; std::size_t _M_item_total; std::size_t _M_count; std::size_t _M_resize; std::size_t _M_cost; }; /** @brief A container size instrumentation line in the stack table. */ class __container_size_stack_info : public __container_size_info { public: __container_size_stack_info(const __container_size_info& __o) : __container_size_info(__o) { } }; /** @brief Container size instrumentation trace producer. */ class __trace_container_size : public __trace_base<__container_size_info, __container_size_stack_info> { public: ~__trace_container_size() { } __trace_container_size() : __trace_base<__container_size_info, __container_size_stack_info>() { }; // Insert a new node at construct with object, callstack and initial size. __container_size_info* __insert(__stack_t __stack, std::size_t __num) { __container_size_info* __ret = __add_object(__stack); if (__ret) __ret->__init(__num); return __ret; } // Call at destruction/clean to set container final size. void __destruct(__container_size_info* __obj_info, std::size_t __num, std::size_t __inum) { __obj_info->__destruct(__num, __inum); __retire_object(__obj_info); } }; } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_CONTAINER_SIZE_H */ 8/profile/impl/profiler_map_to_unordered_map.h000064400000015651152526447520015576 0ustar00// -*- C++ -*- // // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_map_to_unordered_map.h * @brief Diagnostics for map to unordered_map. */ // Written by Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H #define _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H 1 #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" namespace __gnu_profile { inline int __log2(std::size_t __size) { for (int __bit_count = sizeof(std::size_t) - 1; __bit_count >= 0; -- __bit_count) if ((2 << __bit_count) & __size) return __bit_count; return 0; } inline float __map_insert_cost(std::size_t __size) { return (_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor).__value * static_cast(__log2(__size))); } inline float __map_erase_cost(std::size_t __size) { return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value * static_cast(__log2(__size))); } inline float __map_find_cost(std::size_t __size) { return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value * static_cast(__log2(__size))); } /** @brief A map-to-unordered_map instrumentation line in the object table. */ class __map2umap_info : public __object_info_base { public: __map2umap_info(__stack_t __stack) : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0), _M_iterate(0), _M_umap_cost(0.0), _M_map_cost(0.0) { } void __merge(const __map2umap_info& __o) { __object_info_base::__merge(__o); _M_insert += __o._M_insert; _M_erase += __o._M_erase; _M_find += __o._M_find; _M_iterate += __o._M_iterate; _M_umap_cost += __o._M_umap_cost; _M_map_cost += __o._M_map_cost; } void __write(FILE* __f) const { std::fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f\n", _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost, _M_umap_cost); } float __magnitude() const { return _M_map_cost - _M_umap_cost; } std::string __advice() const { return "prefer an unordered container"; } void __record_insert(std::size_t __size, std::size_t __count) { ++_M_insert; if (__count) { _M_map_cost += __count * __map_insert_cost(__size); _M_umap_cost += (__count * _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value); } } void __record_erase(std::size_t __size, std::size_t __count) { ++_M_erase; if (__count) { _M_map_cost += __count * __map_erase_cost(__size); _M_umap_cost += (__count * _GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor).__value); } } void __record_find(std::size_t __size) { ++_M_find; _M_map_cost += __map_find_cost(__size); _M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value; } void __record_iterate(int __count) { __gnu_cxx::__atomic_add(&_M_iterate, __count); } void __set_iterate_costs() { _M_umap_cost += (_M_iterate * _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value); _M_map_cost += (_M_iterate * _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value); } private: std::size_t _M_insert; std::size_t _M_erase; std::size_t _M_find; mutable _Atomic_word _M_iterate; float _M_umap_cost; float _M_map_cost; }; /** @brief A map-to-unordered_map instrumentation line in the stack table. */ class __map2umap_stack_info : public __map2umap_info { public: __map2umap_stack_info(const __map2umap_info& __o) : __map2umap_info(__o) { } }; /** @brief Map-to-unordered_map instrumentation producer. */ class __trace_map2umap : public __trace_base<__map2umap_info, __map2umap_stack_info> { public: __trace_map2umap() : __trace_base<__map2umap_info, __map2umap_stack_info>() { __id = "ordered-to-unordered"; } // Call at destruction/clean to set container final size. void __destruct(__map2umap_info* __obj_info) { __obj_info->__set_iterate_costs(); __retire_object(__obj_info); } }; inline void __trace_map_to_unordered_map_init() { _GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap(); } inline void __trace_map_to_unordered_map_free() { delete _GLIBCXX_PROFILE_DATA(_S_map2umap); } inline void __trace_map_to_unordered_map_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_map2umap), __f, __warnings); } inline __map2umap_info* __trace_map_to_unordered_map_construct() { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_map2umap)->__add_object(__get_stack()); } inline void __trace_map_to_unordered_map_insert(__map2umap_info* __info, std::size_t __size, std::size_t __count) { if (!__info) return; __info->__record_insert(__size, __count); } inline void __trace_map_to_unordered_map_erase(__map2umap_info* __info, std::size_t __size, std::size_t __count) { if (!__info) return; __info->__record_erase(__size, __count); } inline void __trace_map_to_unordered_map_find(__map2umap_info* __info, std::size_t __size) { if (!__info) return; __info->__record_find(__size); } inline void __trace_map_to_unordered_map_iterate(__map2umap_info* __info, int) { if (!__info) return; // We only collect if an iteration took place no matter in what side. __info->__record_iterate(1); } inline void __trace_map_to_unordered_map_invalidate(__map2umap_info* __info) { if (!__info) return; __info->__set_invalid(); } inline void __trace_map_to_unordered_map_destruct(__map2umap_info* __info) { if (!__info) return; _GLIBCXX_PROFILE_DATA(_S_map2umap)->__destruct(__info); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */ 8/profile/impl/profiler_node.h000064400000007331152526447520012334 0ustar00// -*- C++ -*- // // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_node.h * @brief Data structures to represent a single profiling event. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_NODE_H #define _GLIBCXX_PROFILE_PROFILER_NODE_H 1 #include // FILE, fprintf #include #if defined _GLIBCXX_HAVE_EXECINFO_H #include #endif namespace __gnu_profile { typedef void* __instruction_address_t; typedef std::_GLIBCXX_STD_C::vector<__instruction_address_t> __stack_npt; typedef __stack_npt* __stack_t; std::size_t __stack_max_depth(); inline __stack_t __get_stack() { #if defined _GLIBCXX_HAVE_EXECINFO_H __try { std::size_t __max_depth = __stack_max_depth(); if (__max_depth == 0) return 0; __stack_npt __buffer(__max_depth); int __depth = backtrace(&__buffer[0], __max_depth); return new(std::nothrow) __stack_npt(__buffer.begin(), __buffer.begin() + __depth); } __catch(...) { return 0; } #else return 0; #endif } inline std::size_t __size(__stack_t __stack) { if (!__stack) return 0; else return __stack->size(); } // XXX inline void __write(FILE* __f, __stack_t __stack) { if (!__stack) return; __stack_npt::const_iterator __it; for (__it = __stack->begin(); __it != __stack->end(); ++__it) std::fprintf(__f, "%p ", *__it); } /** @brief Hash function for summary trace using call stack as index. */ class __stack_hash { public: std::size_t operator()(__stack_t __s) const { if (!__s) return 0; std::size_t __index = 0; __stack_npt::const_iterator __it; for (__it = __s->begin(); __it != __s->end(); ++__it) __index += reinterpret_cast(*__it); return __index; } bool operator() (__stack_t __stack1, __stack_t __stack2) const { if (!__stack1 && !__stack2) return true; if (!__stack1 || !__stack2) return false; if (__stack1->size() != __stack2->size()) return false; std::size_t __byte_size = __stack1->size() * sizeof(__stack_npt::value_type); return __builtin_memcmp(&(*__stack1)[0], &(*__stack2)[0], __byte_size) == 0; } }; /** @brief Base class for a line in the object table. */ class __object_info_base { public: __object_info_base(__stack_t __stack) : _M_stack(__stack), _M_valid(true) { } bool __is_valid() const { return _M_valid; } void __set_invalid() { _M_valid = false; } void __merge(const __object_info_base& __o) { _M_valid &= __o._M_valid; } __stack_t __stack() const { return _M_stack; } protected: __stack_t _M_stack; bool _M_valid; }; } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_NODE_H */ 8/profile/impl/profiler_list_to_vector.h000064400000015273152526447520014452 0ustar00// -*- C++ -*- // // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_list_to_vector.h * @brief diagnostics for list to vector. */ // Written by Changhee Jung. #ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H #define _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H 1 #include #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" namespace __gnu_profile { /** @brief A list-to-vector instrumentation line in the object table. */ class __list2vector_info : public __object_info_base { public: __list2vector_info(__stack_t __stack) : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0), _M_vector_cost(0), _M_max_size(0) { } void __merge(const __list2vector_info& __o) { __object_info_base::__merge(__o); _M_shift_count += __o._M_shift_count; _M_iterate += __o._M_iterate; _M_vector_cost += __o._M_vector_cost; _M_list_cost += __o._M_list_cost; _M_resize += __o._M_resize; _M_max_size = std::max( _M_max_size, __o._M_max_size); } void __write(FILE* __f) const { std::fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count, _M_resize, _M_iterate, _M_vector_cost, _M_list_cost); } float __magnitude() const { return _M_list_cost - _M_vector_cost; } std::string __advice() const { std::stringstream __sstream; __sstream << "change std::list to std::vector and its initial size from 0 to " << _M_max_size; return __sstream.str(); } std::size_t __shift_count() { return _M_shift_count; } std::size_t __iterate() { return _M_iterate; } float __list_cost() { return _M_list_cost; } std::size_t __resize() { return _M_resize; } void __set_list_cost(float __lc) { _M_list_cost = __lc; } void __set_vector_cost(float __vc) { _M_vector_cost = __vc; } void __opr_insert(std::size_t __shift, std::size_t __size) { _M_shift_count += __shift; _M_max_size = std::max(_M_max_size, __size); } void __opr_iterate(int __num) { __gnu_cxx::__atomic_add(&_M_iterate, __num); } void __resize(std::size_t __from, std::size_t) { _M_resize += __from; } private: std::size_t _M_shift_count; mutable _Atomic_word _M_iterate; std::size_t _M_resize; float _M_list_cost; float _M_vector_cost; std::size_t _M_max_size; }; class __list2vector_stack_info : public __list2vector_info { public: __list2vector_stack_info(const __list2vector_info& __o) : __list2vector_info(__o) {} }; class __trace_list_to_vector : public __trace_base<__list2vector_info, __list2vector_stack_info> { public: __trace_list_to_vector() : __trace_base<__list2vector_info, __list2vector_stack_info>() { __id = "list-to-vector"; } ~__trace_list_to_vector() { } // Call at destruction/clean to set container final size. void __destruct(__list2vector_info* __obj_info) { float __vc = __vector_cost(__obj_info->__shift_count(), __obj_info->__iterate()); float __lc = __list_cost(__obj_info->__shift_count(), __obj_info->__iterate()); __obj_info->__set_vector_cost(__vc); __obj_info->__set_list_cost(__lc); __retire_object(__obj_info); } // Collect cost of operations. float __vector_cost(std::size_t __shift, std::size_t __iterate) { // The resulting vector will use a 'reserve' method. return (__shift * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value + __iterate * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value); } float __list_cost(std::size_t __shift, std::size_t __iterate) { return (__shift * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value + __iterate * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value); } }; inline void __trace_list_to_vector_init() { _GLIBCXX_PROFILE_DATA(_S_list_to_vector) = new __trace_list_to_vector(); } inline void __trace_list_to_vector_free() { delete _GLIBCXX_PROFILE_DATA(_S_list_to_vector); } inline void __trace_list_to_vector_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_list_to_vector), __f, __warnings); } inline __list2vector_info* __trace_list_to_vector_construct() { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_list_to_vector) ->__add_object(__get_stack()); } inline void __trace_list_to_vector_insert(__list2vector_info* __obj_info, std::size_t __shift, std::size_t __size) { if (!__obj_info) return; __obj_info->__opr_insert(__shift, __size); } inline void __trace_list_to_vector_iterate(__list2vector_info* __obj_info, int) { if (!__obj_info) return; // We only collect if an iteration took place no matter in what side. __obj_info->__opr_iterate(1); } inline void __trace_list_to_vector_invalid_operator(__list2vector_info* __obj_info) { if (!__obj_info) return; __obj_info->__set_invalid(); } inline void __trace_list_to_vector_resize(__list2vector_info* __obj_info, std::size_t __from, std::size_t __to) { if (!__obj_info) return; __obj_info->__resize(__from, __to); } inline void __trace_list_to_vector_destruct(__list2vector_info* __obj_info) { if (!__obj_info) return; _GLIBCXX_PROFILE_DATA(_S_list_to_vector)->__destruct(__obj_info); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_VECTOR_H__ */ 8/profile/impl/profiler_hashtable_size.h000064400000005646152526447520014403 0ustar00// -*- C++ -*- // // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_hashtable_size.h * @brief Collection of hashtable size traces. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_HASHTABLE_SIZE_H #define _GLIBCXX_PROFILE_PROFILER_HASHTABLE_SIZE_H 1 #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" #include "profile/impl/profiler_state.h" #include "profile/impl/profiler_container_size.h" namespace __gnu_profile { /** @brief Hashtable size instrumentation trace producer. */ class __trace_hashtable_size : public __trace_container_size { public: __trace_hashtable_size() : __trace_container_size() { __id = "hashtable-size"; } }; inline void __trace_hashtable_size_init() { _GLIBCXX_PROFILE_DATA(_S_hashtable_size) = new __trace_hashtable_size(); } inline void __trace_hashtable_size_free() { delete _GLIBCXX_PROFILE_DATA(_S_hashtable_size); } inline void __trace_hashtable_size_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_hashtable_size), __f, __warnings); } inline __container_size_info* __trace_hashtable_size_construct(std::size_t __num) { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_hashtable_size)-> __insert(__get_stack(), __num); } inline void __trace_hashtable_size_resize(__container_size_info* __obj_info, std::size_t __from, std::size_t __to) { if (!__obj_info) return; __obj_info->__resize(__from, __to); } inline void __trace_hashtable_size_destruct(__container_size_info* __obj_info, std::size_t __num, std::size_t __inum) { if (!__obj_info) return; _GLIBCXX_PROFILE_DATA(_S_hashtable_size)-> __destruct(__obj_info, __num, __inum); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_HASHTABLE_SIZE_H */ 8/profile/impl/profiler_algos.h000064400000006545152526447520012522 0ustar00// -*- C++ -*- // // Copyright (C) 2010-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_algos.h * @brief Algorithms used by the profile extension. * * This file is needed to avoid including \ or \. * Including those files would result in recursive includes. * These implementations are oversimplified. In general, efficiency may be * sacrificed to minimize maintenance overhead. */ #ifndef _GLIBCXX_PROFILE_PROFILER_ALGOS_H #define _GLIBCXX_PROFILE_PROFILER_ALGOS_H 1 namespace __gnu_profile { /* Helper for __top_n. Insert in sorted vector, but not beyond Nth elem. */ template void __insert_top_n(_Container& __output, const typename _Container::value_type& __value, typename _Container::size_type __n) { typename _Container::iterator __it = __output.begin(); typename _Container::size_type __count = 0; // Skip up to N - 1 elements larger than VALUE. // XXX: Could do binary search for random iterators. while (true) { if (__count >= __n) // VALUE is not in top N. return; if (__it == __output.end()) break; if (*__it < __value) break; ++__it; ++__count; } __output.insert(__it, __value); } /* Copy the top N elements in INPUT, sorted in reverse order, to OUTPUT. */ template void __top_n(const _Container& __input, _Container& __output, typename _Container::size_type __n) { __output.clear(); typename _Container::const_iterator __it; for (__it = __input.begin(); __it != __input.end(); ++__it) __insert_top_n(__output, *__it, __n); } /* Simplified clone of std::for_each. */ template _Function __for_each(_InputIterator __first, _InputIterator __last, _Function __f) { for (; __first != __last; ++__first) __f(*__first); return __f; } /* Simplified clone of std::remove. */ template _ForwardIterator __remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { if(__first == __last) return __first; _ForwardIterator __result = __first; ++__first; for(; __first != __last; ++__first) if(!(*__first == __value)) { *__result = *__first; ++__result; } return __result; } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_ALGOS_H */ 8/profile/impl/profiler_state.h000064400000003724152526447520012531 0ustar00// -*- C++ -*- // // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_state.h * @brief Global profiler state. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_STATE_H #define _GLIBCXX_PROFILE_PROFILER_STATE_H 1 namespace __gnu_profile { enum __state_type { __ON, __OFF, __INVALID }; _GLIBCXX_PROFILE_DEFINE_DATA(__state_type, __state, __INVALID); inline bool __turn(__state_type __s) { __state_type inv(__INVALID); return __atomic_compare_exchange_n(&_GLIBCXX_PROFILE_DATA(__state), &inv, __s, false, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); } inline bool __turn_on() { return __turn(__ON); } inline bool __turn_off() { return __turn(__OFF); } inline bool __is_on() { return _GLIBCXX_PROFILE_DATA(__state) == __ON; } inline bool __is_off() { return _GLIBCXX_PROFILE_DATA(__state) == __OFF; } inline bool __is_invalid() { return _GLIBCXX_PROFILE_DATA(__state) == __INVALID; } } // end namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_STATE_H */ 8/profile/impl/profiler_vector_to_list.h000064400000015335152526447520014451 0ustar00// -*- C++ -*- // // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_vector_to_list.h * @brief diagnostics for vector to list. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H #define _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H 1 #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" namespace __gnu_profile { /** @brief A vector-to-list instrumentation line in the object table. */ class __vector2list_info : public __object_info_base { public: __vector2list_info(__stack_t __stack) : __object_info_base(__stack), _M_shift_count(0), _M_iterate(0), _M_resize(0), _M_list_cost(0), _M_vector_cost(0) { } void __merge(const __vector2list_info& __o) { __object_info_base::__merge(__o); _M_shift_count += __o._M_shift_count; _M_iterate += __o._M_iterate; _M_vector_cost += __o._M_vector_cost; _M_list_cost += __o._M_list_cost; _M_resize += __o._M_resize; } void __write(FILE* __f) const { std::fprintf(__f, "%Zu %Zu %Zu %.0f %.0f\n", _M_shift_count, _M_resize, _M_iterate, _M_vector_cost, _M_list_cost); } float __magnitude() const { return _M_vector_cost - _M_list_cost; } std::string __advice() const { return "change std::vector to std::list"; } std::size_t __shift_count() { return _M_shift_count; } std::size_t __iterate() { return _M_iterate; } float __list_cost() { return _M_list_cost; } std::size_t __resize() { return _M_resize; } void __set_list_cost(float __lc) { _M_list_cost = __lc; } void __set_vector_cost(float __vc) { _M_vector_cost = __vc; } void __opr_insert(std::size_t __pos, std::size_t __num) { _M_shift_count += __num - __pos; } void __opr_iterate(int __num) { __gnu_cxx::__atomic_add(&_M_iterate, __num); } void __resize(std::size_t __from, std::size_t) { _M_resize += __from; } private: std::size_t _M_shift_count; mutable _Atomic_word _M_iterate; std::size_t _M_resize; float _M_list_cost; float _M_vector_cost; }; /** @brief A vector-to-list instrumentation line in the stack table. */ class __vector2list_stack_info : public __vector2list_info { public: __vector2list_stack_info(const __vector2list_info& __o) : __vector2list_info(__o) { } }; /** @brief Vector-to-list instrumentation producer. */ class __trace_vector_to_list : public __trace_base<__vector2list_info, __vector2list_stack_info> { public: __trace_vector_to_list() : __trace_base<__vector2list_info, __vector2list_stack_info>() { __id = "vector-to-list"; } ~__trace_vector_to_list() { } // Call at destruction/clean to set container final size. void __destruct(__vector2list_info* __obj_info) { float __vc = __vector_cost(__obj_info->__shift_count(), __obj_info->__iterate(), __obj_info->__resize()); float __lc = __list_cost(__obj_info->__shift_count(), __obj_info->__iterate(), __obj_info->__resize()); __obj_info->__set_vector_cost(__vc); __obj_info->__set_list_cost(__lc); __retire_object(__obj_info); } // Collect cost of operations. float __vector_cost(std::size_t __shift, std::size_t __iterate, std::size_t __resize) { return (__shift * _GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor).__value + __iterate * _GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor).__value + __resize * _GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor).__value); } float __list_cost(std::size_t __shift, std::size_t __iterate, std::size_t __resize) { return (__shift * _GLIBCXX_PROFILE_DATA(__list_shift_cost_factor).__value + __iterate * _GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor).__value + __resize * _GLIBCXX_PROFILE_DATA(__list_resize_cost_factor).__value); } }; inline void __trace_vector_to_list_init() { _GLIBCXX_PROFILE_DATA(_S_vector_to_list) = new __trace_vector_to_list(); } inline void __trace_vector_to_list_free() { delete _GLIBCXX_PROFILE_DATA(_S_vector_to_list); } inline void __trace_vector_to_list_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_vector_to_list), __f, __warnings); } inline __vector2list_info* __trace_vector_to_list_construct() { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_vector_to_list) ->__add_object(__get_stack()); } inline void __trace_vector_to_list_insert(__vector2list_info* __obj_info, std::size_t __pos, std::size_t __num) { if (!__obj_info) return; __obj_info->__opr_insert(__pos, __num); } inline void __trace_vector_to_list_iterate(__vector2list_info* __obj_info, int) { if (!__obj_info) return; // We only collect if an iteration took place no matter in what side. __obj_info->__opr_iterate(1); } inline void __trace_vector_to_list_invalid_operator(__vector2list_info* __obj_info) { if (!__obj_info) return; __obj_info->__set_invalid(); } inline void __trace_vector_to_list_resize(__vector2list_info* __obj_info, std::size_t __from, std::size_t __to) { if (!__obj_info) return; __obj_info->__resize(__from, __to); } inline void __trace_vector_to_list_destruct(__vector2list_info* __obj_info) { if (!__obj_info) return; _GLIBCXX_PROFILE_DATA(_S_vector_to_list)->__destruct(__obj_info); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_TO_LIST_H */ 8/profile/impl/profiler_hash_func.h000064400000010474152526447520013347 0ustar00// -*- C++ -*- // // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_hash_func.h * @brief Data structures to represent profiling traces. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H #define _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H 1 #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" namespace __gnu_profile { /** @brief A hash performance instrumentation line in the object table. */ class __hashfunc_info : public __object_info_base { public: __hashfunc_info(__stack_t __stack) : __object_info_base(__stack), _M_longest_chain(0), _M_accesses(0), _M_hops(0) { } void __merge(const __hashfunc_info& __o) { __object_info_base::__merge(__o); _M_longest_chain = std::max(_M_longest_chain, __o._M_longest_chain); _M_accesses += __o._M_accesses; _M_hops += __o._M_hops; } void __destruct(std::size_t __chain, std::size_t __accesses, std::size_t __hops) { _M_longest_chain = std::max(_M_longest_chain, __chain); _M_accesses += __accesses; _M_hops += __hops; } void __write(FILE* __f) const { std::fprintf(__f, "%Zu %Zu %Zu\n", _M_hops, _M_accesses, _M_longest_chain); } float __magnitude() const { return static_cast(_M_hops); } std::string __advice() const { return "change hash function"; } private: std::size_t _M_longest_chain; std::size_t _M_accesses; std::size_t _M_hops; }; /** @brief A hash performance instrumentation line in the stack table. */ class __hashfunc_stack_info : public __hashfunc_info { public: __hashfunc_stack_info(const __hashfunc_info& __o) : __hashfunc_info(__o) { } }; /** @brief Hash performance instrumentation producer. */ class __trace_hash_func : public __trace_base<__hashfunc_info, __hashfunc_stack_info> { public: __trace_hash_func() : __trace_base<__hashfunc_info, __hashfunc_stack_info>() { __id = "hash-distr"; } ~__trace_hash_func() {} // Call at destruction/clean to set container final size. void __destruct(__hashfunc_info* __obj_info, std::size_t __chain, std::size_t __accesses, std::size_t __hops) { if (!__obj_info) return; __obj_info->__destruct(__chain, __accesses, __hops); __retire_object(__obj_info); } }; inline void __trace_hash_func_init() { _GLIBCXX_PROFILE_DATA(_S_hash_func) = new __trace_hash_func(); } inline void __trace_hash_func_free() { delete _GLIBCXX_PROFILE_DATA(_S_hash_func); } inline void __trace_hash_func_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_hash_func), __f, __warnings); } inline __hashfunc_info* __trace_hash_func_construct() { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_hash_func)->__add_object(__get_stack()); } inline void __trace_hash_func_destruct(__hashfunc_info* __obj_info, std::size_t __chain, std::size_t __accesses, std::size_t __hops) { _GLIBCXX_PROFILE_DATA(_S_hash_func)->__destruct(__obj_info, __chain, __accesses, __hops); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_HASH_FUNC_H */ 8/profile/impl/profiler_trace.h000064400000050613152526447520012506 0ustar00// -*- C++ -*- // // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_trace.h * @brief Data structures to represent profiling traces. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_TRACE_H #define _GLIBCXX_PROFILE_PROFILER_TRACE_H 1 #include // fopen, fclose, fprintf, FILE #include #include // atof, atoi, strtol, getenv, atexit, abort #if __cplusplus >= 201103L #include #define _GLIBCXX_IMPL_UNORDERED_MAP std::_GLIBCXX_STD_C::unordered_map #else #include #define _GLIBCXX_IMPL_UNORDERED_MAP std::tr1::unordered_map #endif #include #include #include #include #include #include "profile/impl/profiler_algos.h" #include "profile/impl/profiler_state.h" #include "profile/impl/profiler_node.h" namespace __gnu_profile { /** @brief Internal environment. Values can be set one of two ways: 1. In config file "var = value". The default config file path is libstdcxx-profile.conf. 2. By setting process environment variables. For instance, in a Bash shell you can set the unit cost of iterating through a map like this: export __map_iterate_cost_factor=5.0. If a value is set both in the input file and through an environment variable, the environment value takes precedence. */ typedef _GLIBCXX_IMPL_UNORDERED_MAP __env_t; _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__env_t, __env); /** @brief Master lock. */ _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__gnu_cxx::__mutex, __global_mutex); /** @brief Representation of a warning. */ struct __warning_data { float __magnitude; __stack_t __context; const char* __warning_id; std::string __warning_message; __warning_data() : __magnitude(0.0), __context(0), __warning_id(0) { } __warning_data(float __m, __stack_t __c, const char* __id, const std::string& __msg) : __magnitude(__m), __context(__c), __warning_id(__id), __warning_message(__msg) { } bool operator<(const __warning_data& __other) const { return __magnitude < __other.__magnitude; } }; typedef std::_GLIBCXX_STD_C::vector<__warning_data> __warning_vector_t; // Defined in profiler_.h. class __trace_hash_func; class __trace_hashtable_size; class __trace_map2umap; class __trace_vector_size; class __trace_vector_to_list; class __trace_list_to_slist; class __trace_list_to_vector; void __trace_vector_size_init(); void __trace_hashtable_size_init(); void __trace_hash_func_init(); void __trace_vector_to_list_init(); void __trace_list_to_slist_init(); void __trace_list_to_vector_init(); void __trace_map_to_unordered_map_init(); void __trace_vector_size_report(FILE*, __warning_vector_t&); void __trace_hashtable_size_report(FILE*, __warning_vector_t&); void __trace_hash_func_report(FILE*, __warning_vector_t&); void __trace_vector_to_list_report(FILE*, __warning_vector_t&); void __trace_list_to_slist_report(FILE*, __warning_vector_t&); void __trace_list_to_vector_report(FILE*, __warning_vector_t&); void __trace_map_to_unordered_map_report(FILE*, __warning_vector_t&); void __trace_vector_size_free(); void __trace_hashtable_size_free(); void __trace_hash_func_free(); void __trace_vector_to_list_free(); void __trace_list_to_slist_free(); void __trace_list_to_vector_free(); void __trace_map_to_unordered_map_free(); struct __cost_factor { const char* __env_var; float __value; }; typedef std::_GLIBCXX_STD_C::vector<__cost_factor*> __cost_factor_vector; _GLIBCXX_PROFILE_DEFINE_DATA(__trace_hash_func*, _S_hash_func, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__trace_hashtable_size*, _S_hashtable_size, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__trace_map2umap*, _S_map2umap, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_size*, _S_vector_size, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_to_list*, _S_vector_to_list, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_slist*, _S_list_to_slist, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_vector*, _S_list_to_vector, 0); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_shift_cost_factor, {"__vector_shift_cost_factor", 1.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_iterate_cost_factor, {"__vector_iterate_cost_factor", 1.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_resize_cost_factor, {"__vector_resize_cost_factor", 1.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_shift_cost_factor, {"__list_shift_cost_factor", 0.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_iterate_cost_factor, {"__list_iterate_cost_factor", 10.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_resize_cost_factor, {"__list_resize_cost_factor", 0.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_insert_cost_factor, {"__map_insert_cost_factor", 1.5}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_erase_cost_factor, {"__map_erase_cost_factor", 1.5}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_find_cost_factor, {"__map_find_cost_factor", 1}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_iterate_cost_factor, {"__map_iterate_cost_factor", 2.3}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_insert_cost_factor, {"__umap_insert_cost_factor", 12.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_erase_cost_factor, {"__umap_erase_cost_factor", 12.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_find_cost_factor, {"__umap_find_cost_factor", 10.0}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_iterate_cost_factor, {"__umap_iterate_cost_factor", 1.7}); _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor_vector*, __cost_factors, 0); _GLIBCXX_PROFILE_DEFINE_DATA(const char*, _S_trace_file_name, _GLIBCXX_PROFILE_TRACE_PATH_ROOT); _GLIBCXX_PROFILE_DEFINE_DATA(std::size_t, _S_max_warn_count, _GLIBCXX_PROFILE_MAX_WARN_COUNT); _GLIBCXX_PROFILE_DEFINE_DATA(std::size_t, _S_max_stack_depth, _GLIBCXX_PROFILE_MAX_STACK_DEPTH); _GLIBCXX_PROFILE_DEFINE_DATA(std::size_t, _S_max_mem, _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC); inline std::size_t __stack_max_depth() { return _GLIBCXX_PROFILE_DATA(_S_max_stack_depth); } inline std::size_t __max_mem() { return _GLIBCXX_PROFILE_DATA(_S_max_mem); } /** @brief Base class for all trace producers. */ template class __trace_base { public: // Do not pick the initial size too large, as we don't know which // diagnostics are more active. __trace_base() : __objects_byte_size(0), __stack_table(10000), __stack_table_byte_size(0), __id(0) { } ~__trace_base() { for (typename __stack_table_t::iterator __it = __stack_table.begin(); __it != __stack_table.end(); ++__it) delete __it->first; } __object_info* __add_object(__stack_t __stack); void __retire_object(__object_info* __info); void __write(FILE* __f); void __collect_warnings(__warning_vector_t& __warnings); void __free(); private: __gnu_cxx::__mutex __trace_mutex; typedef _GLIBCXX_IMPL_UNORDERED_MAP<__stack_t, __stack_info, __stack_hash, __stack_hash> __stack_table_t; std::size_t __objects_byte_size; __stack_table_t __stack_table; std::size_t __stack_table_byte_size; protected: const char* __id; }; template __object_info* __trace_base<__object_info, __stack_info>:: __add_object(__stack_t __stack) { // If we have no backtrace information no need to collect data. if (!__stack) return 0; __gnu_cxx::__scoped_lock __lock(this->__trace_mutex); if (__max_mem() != 0 && __objects_byte_size >= __max_mem()) { delete __stack; return 0; } __object_info* __ret = new(std::nothrow) __object_info(__stack); if (!__ret) { delete __stack; return 0; } __objects_byte_size += sizeof(__object_info); return __ret; } template void __trace_base<__object_info, __stack_info>:: __retire_object(__object_info* __obj_info) { if (!__obj_info) return; __gnu_cxx::__scoped_lock __lock(this->__trace_mutex); const __object_info& __info = *__obj_info; __stack_t __stack = __info.__stack(); typename __stack_table_t::iterator __stack_it = __stack_table.find(__stack); if (__stack_it == __stack_table.end()) { // First occurrence of this call context. if (__max_mem() == 0 || __stack_table_byte_size < __max_mem()) { __stack_table_byte_size += (sizeof(__instruction_address_t) * __size(__stack) + sizeof(__stack) + sizeof(__stack_info)); __stack_table.insert(make_pair(__stack, __stack_info(__info))); } else delete __stack; } else { // Merge object info into info summary for this call context. __stack_it->second.__merge(__info); delete __stack; } delete __obj_info; __objects_byte_size -= sizeof(__object_info); } template void __trace_base<__object_info, __stack_info>:: __write(FILE* __f) { for (typename __stack_table_t::iterator __it = __stack_table.begin(); __it != __stack_table.end(); ++__it) if (__it->second.__is_valid()) { std::fprintf(__f, __id); std::fprintf(__f, "|"); __gnu_profile::__write(__f, __it->first); std::fprintf(__f, "|"); __it->second.__write(__f); } } template void __trace_base<__object_info, __stack_info>:: __collect_warnings(__warning_vector_t& __warnings) { for (typename __stack_table_t::iterator __it = __stack_table.begin(); __it != __stack_table.end(); ++__it) __warnings.push_back(__warning_data(__it->second.__magnitude(), __it->first, __id, __it->second.__advice())); } template inline void __trace_report(__trace_base<__object_info, __stack_info>* __cont, FILE* __f, __warning_vector_t& __warnings) { if (__cont) { __cont->__collect_warnings(__warnings); __cont->__write(__f); } } inline std::size_t __env_to_size_t(const char* __env_var, std::size_t __default_value) { char* __env_value = std::getenv(__env_var); if (__env_value) { errno = 0; long __converted_value = std::strtol(__env_value, 0, 10); if (errno || __converted_value < 0) { std::fprintf(stderr, "Bad value for environment variable '%s'.\n", __env_var); std::abort(); } else return static_cast(__converted_value); } else return __default_value; } inline void __set_max_stack_trace_depth() { _GLIBCXX_PROFILE_DATA(_S_max_stack_depth) = __env_to_size_t(_GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR, _GLIBCXX_PROFILE_DATA(_S_max_stack_depth)); } inline void __set_max_mem() { _GLIBCXX_PROFILE_DATA(_S_max_mem) = __env_to_size_t(_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR, _GLIBCXX_PROFILE_DATA(_S_max_mem)); } inline int __log_magnitude(float __f) { const float __log_base = 10.0; int __result = 0; int __sign = 1; if (__f < 0) { __f = -__f; __sign = -1; } while (__f > __log_base) { ++__result; __f /= 10.0; } return __sign * __result; } inline FILE* __open_output_file(const char* __extension) { // The path is made of _S_trace_file_name + "." + extension. std::size_t __root_len = __builtin_strlen(_GLIBCXX_PROFILE_DATA(_S_trace_file_name)); std::size_t __ext_len = __builtin_strlen(__extension); char* __file_name = new char[__root_len + 1 + __ext_len + 1]; __builtin_memcpy(__file_name, _GLIBCXX_PROFILE_DATA(_S_trace_file_name), __root_len); *(__file_name + __root_len) = '.'; __builtin_memcpy(__file_name + __root_len + 1, __extension, __ext_len + 1); FILE* __out_file = std::fopen(__file_name, "w"); if (!__out_file) { std::fprintf(stderr, "Could not open trace file '%s'.\n", __file_name); std::abort(); } delete[] __file_name; return __out_file; } struct __warn { FILE* __file; __warn(FILE* __f) { __file = __f; } void operator()(const __warning_data& __info) { std::fprintf(__file, __info.__warning_id); std::fprintf(__file, ": improvement = %d", __log_magnitude(__info.__magnitude)); std::fprintf(__file, ": call stack = "); __gnu_profile::__write(__file, __info.__context); std::fprintf(__file, ": advice = %s\n", __info.__warning_message.c_str()); } }; /** @brief Final report method, registered with @b atexit. * * This can also be called directly by user code, including signal handlers. * It is protected against deadlocks by the reentrance guard in profiler.h. * However, when called from a signal handler that triggers while within * __gnu_profile (under the guarded zone), no output will be produced. */ inline void __report() { __gnu_cxx::__scoped_lock __lock(_GLIBCXX_PROFILE_DATA(__global_mutex)); __warning_vector_t __warnings, __top_warnings; FILE* __raw_file = __open_output_file("raw"); __trace_vector_size_report(__raw_file, __warnings); __trace_hashtable_size_report(__raw_file, __warnings); __trace_hash_func_report(__raw_file, __warnings); __trace_vector_to_list_report(__raw_file, __warnings); __trace_list_to_slist_report(__raw_file, __warnings); __trace_list_to_vector_report(__raw_file, __warnings); __trace_map_to_unordered_map_report(__raw_file, __warnings); std::fclose(__raw_file); // Sort data by magnitude, keeping just top N. std::size_t __cutoff = std::min(_GLIBCXX_PROFILE_DATA(_S_max_warn_count), __warnings.size()); __top_n(__warnings, __top_warnings, __cutoff); FILE* __warn_file = __open_output_file("txt"); __for_each(__top_warnings.begin(), __top_warnings.end(), __warn(__warn_file)); std::fclose(__warn_file); } inline void __report_and_free() { __report(); __trace_map_to_unordered_map_free(); __trace_list_to_vector_free(); __trace_list_to_slist_free(); __trace_vector_to_list_free(); __trace_hash_func_free(); __trace_hashtable_size_free(); __trace_vector_size_free(); delete _GLIBCXX_PROFILE_DATA(__cost_factors); } inline void __set_trace_path() { char* __env_trace_file_name = std::getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR); if (__env_trace_file_name) _GLIBCXX_PROFILE_DATA(_S_trace_file_name) = __env_trace_file_name; // Make sure early that we can create the trace file. std::fclose(__open_output_file("txt")); } inline void __set_max_warn_count() { char* __env_max_warn_count_str = std::getenv(_GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR); if (__env_max_warn_count_str) _GLIBCXX_PROFILE_DATA(_S_max_warn_count) = static_cast(std::atoi(__env_max_warn_count_str)); } inline void __read_cost_factors() { std::string __conf_file_name(_GLIBCXX_PROFILE_DATA(_S_trace_file_name)); __conf_file_name += ".conf"; std::ifstream __conf_file(__conf_file_name.c_str()); if (__conf_file.is_open()) { std::string __line; while (std::getline(__conf_file, __line)) { std::string::size_type __i = __line.find_first_not_of(" \t\n\v"); if (__line.length() <= 0 || __line[__i] == '#') // Skip empty lines or comments. continue; } // Trim. __line.erase(__remove(__line.begin(), __line.end(), ' '), __line.end()); std::string::size_type __pos = __line.find("="); std::string __factor_name = __line.substr(0, __pos); std::string::size_type __end = __line.find_first_of(";\n"); std::string __factor_value = __line.substr(__pos + 1, __end - __pos); _GLIBCXX_PROFILE_DATA(__env)[__factor_name] = __factor_value; } } struct __cost_factor_writer { FILE* __file; __cost_factor_writer(FILE* __f) : __file(__f) { } void operator() (const __cost_factor* __factor) { std::fprintf(__file, "%s = %f\n", __factor->__env_var, __factor->__value); } }; inline void __write_cost_factors() { FILE* __file = __open_output_file("conf.out"); __for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(), _GLIBCXX_PROFILE_DATA(__cost_factors)->end(), __cost_factor_writer(__file)); std::fclose(__file); } struct __cost_factor_setter { void operator()(__cost_factor* __factor) { // Look it up in the process environment first. const char* __env_value = std::getenv(__factor->__env_var); if (!__env_value) { // Look it up in the config file. __env_t::iterator __it = _GLIBCXX_PROFILE_DATA(__env).find(__factor->__env_var); if (__it != _GLIBCXX_PROFILE_DATA(__env).end()) __env_value = __it->second.c_str(); } if (__env_value) __factor->__value = std::atof(__env_value); } }; inline void __set_cost_factors() { __cost_factor_vector* __factors = new __cost_factor_vector; _GLIBCXX_PROFILE_DATA(__cost_factors) = __factors; __factors->push_back(&_GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__list_shift_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__list_resize_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__map_find_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__umap_find_cost_factor)); __factors->push_back(&_GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor)); __for_each(__factors->begin(), __factors->end(), __cost_factor_setter()); } inline void __profcxx_init_unconditional() { __gnu_cxx::__scoped_lock __lock(_GLIBCXX_PROFILE_DATA(__global_mutex)); if (__is_invalid()) { __set_max_warn_count(); if (_GLIBCXX_PROFILE_DATA(_S_max_warn_count) == 0) __turn_off(); else { __set_max_stack_trace_depth(); __set_max_mem(); __set_trace_path(); __read_cost_factors(); __set_cost_factors(); __write_cost_factors(); __trace_vector_size_init(); __trace_hashtable_size_init(); __trace_hash_func_init(); __trace_vector_to_list_init(); __trace_list_to_slist_init(); __trace_list_to_vector_init(); __trace_map_to_unordered_map_init(); std::atexit(__report_and_free); __turn_on(); } } } /** @brief This function must be called by each instrumentation point. * * The common path is inlined fully. */ inline bool __profcxx_init() { if (__is_invalid()) __profcxx_init_unconditional(); return __is_on(); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_TRACE_H */ 8/profile/impl/profiler_list_to_slist.h000064400000010526152526447520014302 0ustar00// -*- C++ -*- // // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_list_to_slist.h * @brief Diagnostics for list to slist. */ // Written by Changhee Jung. #ifndef _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H #define _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H 1 #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" namespace __gnu_profile { class __list2slist_info : public __object_info_base { public: __list2slist_info(__stack_t __stack) : __object_info_base(__stack), _M_rewind(false), _M_operations(0) { } // XXX: the magnitude should be multiplied with a constant factor F, // where F is 1 when the malloc size class of list nodes is different // from the malloc size class of slist nodes. When they fall into the same // class, the only slist benefit is from having to set fewer links, so // the factor F should be much smaller, closer to 0 than to 1. // This could be implemented by passing the size classes in the config // file. For now, we always assume F to be 1. float __magnitude() const { if (!_M_rewind) return _M_operations; else return 0; } void __write(FILE* __f) const { std::fprintf(__f, "%s\n", _M_rewind ? "invalid" : "valid"); } std::string __advice() const { return "change std::list to std::forward_list"; } void __opr_rewind() { _M_rewind = true; __set_invalid(); } void __record_operation() { ++_M_operations; } bool __has_rewind() { return _M_rewind; } private: bool _M_rewind; std::size_t _M_operations; }; class __list2slist_stack_info : public __list2slist_info { public: __list2slist_stack_info(const __list2slist_info& __o) : __list2slist_info(__o) { } }; class __trace_list_to_slist : public __trace_base<__list2slist_info, __list2slist_stack_info> { public: ~__trace_list_to_slist() { } __trace_list_to_slist() : __trace_base<__list2slist_info, __list2slist_stack_info>() { __id = "list-to-slist"; } void __destruct(__list2slist_info* __obj_info) { __retire_object(__obj_info); } }; inline void __trace_list_to_slist_init() { _GLIBCXX_PROFILE_DATA(_S_list_to_slist) = new __trace_list_to_slist(); } inline void __trace_list_to_slist_free() { delete _GLIBCXX_PROFILE_DATA(_S_list_to_slist); } inline void __trace_list_to_slist_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_list_to_slist), __f, __warnings); } inline __list2slist_info* __trace_list_to_slist_construct() { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__add_object(__get_stack()); } inline void __trace_list_to_slist_rewind(__list2slist_info* __obj_info) { if (!__obj_info) return; __obj_info->__opr_rewind(); } inline void __trace_list_to_slist_operation(__list2slist_info* __obj_info) { if (!__obj_info) return; __obj_info->__record_operation(); } inline void __trace_list_to_slist_destruct(__list2slist_info* __obj_info) { if (!__obj_info) return; _GLIBCXX_PROFILE_DATA(_S_list_to_slist)->__destruct(__obj_info); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_LIST_TO_SLIST_H */ 8/profile/impl/profiler.h000064400000033144152526447520011330 0ustar00// -*- C++ -*- // // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler.h * @brief Interface of the profiling runtime library. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_H #define _GLIBCXX_PROFILE_PROFILER_H 1 #include // Mechanism to define data with inline linkage. #define _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__type, __name) \ inline __type& \ __get_##__name() \ { \ static __type __name; \ return __name; \ } #define _GLIBCXX_PROFILE_DEFINE_DATA(__type, __name, __initial_value...) \ inline __type& __get_##__name() { \ static __type __name(__initial_value); \ return __name; \ } #define _GLIBCXX_PROFILE_DATA(__name) \ __get_##__name() namespace __gnu_profile { /** @brief Reentrance guard. * * Mechanism to protect all __gnu_profile operations against recursion, * multithreaded and exception reentrance. */ struct __reentrance_guard { static bool __get_in() { if (__inside() == true) return false; else { __inside() = true; return true; } } static bool& __inside() { static __thread bool _S_inside(false); return _S_inside; } __reentrance_guard() { } ~__reentrance_guard() { __inside() = false; } }; // Forward declarations of implementation functions. // Don't use any __gnu_profile:: in user code. // Instead, use the __profcxx... macros, which offer guarded access. class __container_size_info; class __hashfunc_info; class __map2umap_info; class __vector2list_info; class __list2slist_info; class __list2vector_info; bool __turn_on(); bool __turn_off(); bool __is_invalid(); bool __is_on(); bool __is_off(); void __report(); __container_size_info* __trace_hashtable_size_construct(std::size_t); void __trace_hashtable_size_resize(__container_size_info*, std::size_t, std::size_t); void __trace_hashtable_size_destruct(__container_size_info*, std::size_t, std::size_t); __hashfunc_info* __trace_hash_func_construct(); void __trace_hash_func_destruct(__hashfunc_info*, std::size_t, std::size_t, std::size_t); __container_size_info* __trace_vector_size_construct(std::size_t); void __trace_vector_size_resize(__container_size_info*, std::size_t, std::size_t); void __trace_vector_size_destruct(__container_size_info*, std::size_t, std::size_t); __vector2list_info* __trace_vector_to_list_construct(); void __trace_vector_to_list_insert(__vector2list_info*, std::size_t, std::size_t); void __trace_vector_to_list_iterate(__vector2list_info*, int); void __trace_vector_to_list_invalid_operator(__vector2list_info*); void __trace_vector_to_list_resize(__vector2list_info*, std::size_t, std::size_t); void __trace_vector_to_list_destruct(__vector2list_info*); __list2slist_info* __trace_list_to_slist_construct(); void __trace_list_to_slist_rewind(__list2slist_info*); void __trace_list_to_slist_operation(__list2slist_info*); void __trace_list_to_slist_destruct(__list2slist_info*); __list2vector_info* __trace_list_to_vector_construct(); void __trace_list_to_vector_insert(__list2vector_info*, std::size_t, std::size_t); void __trace_list_to_vector_iterate(__list2vector_info*, int); void __trace_list_to_vector_invalid_operator(__list2vector_info*); void __trace_list_to_vector_resize(__list2vector_info*, std::size_t, std::size_t); void __trace_list_to_vector_destruct(__list2vector_info*); __map2umap_info* __trace_map_to_unordered_map_construct(); void __trace_map_to_unordered_map_invalidate(__map2umap_info*); void __trace_map_to_unordered_map_insert(__map2umap_info*, std::size_t, std::size_t); void __trace_map_to_unordered_map_erase(__map2umap_info*, std::size_t, std::size_t); void __trace_map_to_unordered_map_iterate(__map2umap_info*, std::size_t); void __trace_map_to_unordered_map_find(__map2umap_info*, std::size_t); void __trace_map_to_unordered_map_destruct(__map2umap_info*); } // namespace __gnu_profile // Master switch turns on all diagnostics that are not explicitly turned off. #ifdef _GLIBCXX_PROFILE #ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_SMALL #define _GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL #endif #ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_LARGE #define _GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE #endif #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_SMALL #define _GLIBCXX_PROFILE_VECTOR_TOO_SMALL #endif #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_LARGE #define _GLIBCXX_PROFILE_VECTOR_TOO_LARGE #endif #ifndef _GLIBCXX_PROFILE_NO_INEFFICIENT_HASH #define _GLIBCXX_PROFILE_INEFFICIENT_HASH #endif #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TO_LIST #define _GLIBCXX_PROFILE_VECTOR_TO_LIST #endif #ifndef _GLIBCXX_PROFILE_NO_LIST_TO_SLIST #define _GLIBCXX_PROFILE_LIST_TO_SLIST #endif #ifndef _GLIBCXX_PROFILE_NO_LIST_TO_VECTOR #define _GLIBCXX_PROFILE_LIST_TO_VECTOR #endif #ifndef _GLIBCXX_PROFILE_NO_MAP_TO_UNORDERED_MAP #define _GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP #endif #endif // Expose global management routines to user code. #ifdef _GLIBCXX_PROFILE #define __profcxx_report() __gnu_profile::__report() #define __profcxx_turn_on() __gnu_profile::__turn_on() #define __profcxx_turn_off() __gnu_profile::__turn_off() #define __profcxx_is_invalid() __gnu_profile::__is_invalid() #define __profcxx_is_on() __gnu_profile::__is_on() #define __profcxx_is_off() __gnu_profile::__is_off() #else #define __profcxx_report() #define __profcxx_turn_on() #define __profcxx_turn_off() #define __profcxx_is_invalid() #define __profcxx_is_on() #define __profcxx_is_off() #endif // Turn on/off instrumentation for HASHTABLE_TOO_SMALL and HASHTABLE_TOO_LARGE. #if (defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL) \ || defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE)) #define __profcxx_hashtable_size_construct(__x...) \ __gnu_profile::__trace_hashtable_size_construct(__x) #define __profcxx_hashtable_size_resize(__x...) \ __gnu_profile::__trace_hashtable_size_resize(__x) #define __profcxx_hashtable_size_destruct(__x...) \ __gnu_profile::__trace_hashtable_size_destruct(__x) #else #define __profcxx_hashtable_size_construct(__x...) 0 #define __profcxx_hashtable_size_resize(__x...) #define __profcxx_hashtable_size_destruct(__x...) #endif // Turn on/off instrumentation for VECTOR_TOO_SMALL and VECTOR_TOO_LARGE. #if (defined(_GLIBCXX_PROFILE_VECTOR_TOO_SMALL) \ || defined(_GLIBCXX_PROFILE_VECTOR_TOO_LARGE)) #define __profcxx_vector_size_construct(__x...) \ __gnu_profile::__trace_vector_size_construct(__x) #define __profcxx_vector_size_resize(__x...) \ __gnu_profile::__trace_vector_size_resize(__x) #define __profcxx_vector_size_destruct(__x...) \ __gnu_profile::__trace_vector_size_destruct(__x) #else #define __profcxx_vector_size_construct(__x...) 0 #define __profcxx_vector_size_resize(__x...) #define __profcxx_vector_size_destruct(__x...) #endif // Turn on/off instrumentation for INEFFICIENT_HASH. #if defined(_GLIBCXX_PROFILE_INEFFICIENT_HASH) #define __profcxx_hash_func_construct(__x...) \ __gnu_profile::__trace_hash_func_construct(__x) #define __profcxx_hash_func_destruct(__x...) \ __gnu_profile::__trace_hash_func_destruct(__x) #else #define __profcxx_hash_func_construct(__x...) 0 #define __profcxx_hash_func_destruct(__x...) #endif // Turn on/off instrumentation for VECTOR_TO_LIST. #if defined(_GLIBCXX_PROFILE_VECTOR_TO_LIST) #define __profcxx_vector2list_construct(__x...) \ __gnu_profile::__trace_vector_to_list_construct(__x) #define __profcxx_vector2list_insert(__x...) \ __gnu_profile::__trace_vector_to_list_insert(__x) #define __profcxx_vector2list_iterate(__x...) \ __gnu_profile::__trace_vector_to_list_iterate(__x) #define __profcxx_vector2list_invalid_operator(__x...) \ __gnu_profile::__trace_vector_to_list_invalid_operator(__x) #define __profcxx_vector2list_resize(__x...) \ __gnu_profile::__trace_vector_to_list_resize(__x) #define __profcxx_vector2list_destruct(__x...) \ __gnu_profile::__trace_vector_to_list_destruct(__x) #else #define __profcxx_vector2list_construct(__x...) 0 #define __profcxx_vector2list_insert(__x...) #define __profcxx_vector2list_iterate(__x...) #define __profcxx_vector2list_invalid_operator(__x...) #define __profcxx_vector2list_resize(__x...) #define __profcxx_vector2list_destruct(__x...) #endif // Turn on/off instrumentation for LIST_TO_VECTOR. #if defined(_GLIBCXX_PROFILE_LIST_TO_VECTOR) #define __profcxx_list2vector_construct(__x...) \ __gnu_profile::__trace_list_to_vector_construct(__x) #define __profcxx_list2vector_insert(__x...) \ __gnu_profile::__trace_list_to_vector_insert(__x) #define __profcxx_list2vector_iterate(__x...) \ __gnu_profile::__trace_list_to_vector_iterate(__x) #define __profcxx_list2vector_invalid_operator(__x...) \ __gnu_profile::__trace_list_to_vector_invalid_operator(__x) #define __profcxx_list2vector_destruct(__x...) \ __gnu_profile::__trace_list_to_vector_destruct(__x) #else #define __profcxx_list2vector_construct(__x...) 0 #define __profcxx_list2vector_insert(__x...) #define __profcxx_list2vector_iterate(__x...) #define __profcxx_list2vector_invalid_operator(__x...) #define __profcxx_list2vector_destruct(__x...) #endif // Turn on/off instrumentation for LIST_TO_SLIST. #if defined(_GLIBCXX_PROFILE_LIST_TO_SLIST) #define __profcxx_list2slist_construct(__x...) \ __gnu_profile::__trace_list_to_slist_construct(__x) #define __profcxx_list2slist_rewind(__x...) \ __gnu_profile::__trace_list_to_slist_rewind(__x) #define __profcxx_list2slist_operation(__x...) \ __gnu_profile::__trace_list_to_slist_operation(__x) #define __profcxx_list2slist_destruct(__x...) \ __gnu_profile::__trace_list_to_slist_destruct(__x) #else #define __profcxx_list2slist_construct(__x...) 0 #define __profcxx_list2slist_rewind(__x...) #define __profcxx_list2slist_operation(__x...) #define __profcxx_list2slist_destruct(__x...) #endif // Turn on/off instrumentation for MAP_TO_UNORDERED_MAP. #if defined(_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP) #define __profcxx_map2umap_construct(__x...) \ __gnu_profile::__trace_map_to_unordered_map_construct(__x) #define __profcxx_map2umap_insert(__x...) \ __gnu_profile::__trace_map_to_unordered_map_insert(__x) #define __profcxx_map2umap_erase(__x...) \ __gnu_profile::__trace_map_to_unordered_map_erase(__x) #define __profcxx_map2umap_iterate(__x...) \ __gnu_profile::__trace_map_to_unordered_map_iterate(__x) #define __profcxx_map2umap_invalidate(__x...) \ __gnu_profile::__trace_map_to_unordered_map_invalidate(__x) #define __profcxx_map2umap_find(__x...) \ __gnu_profile::__trace_map_to_unordered_map_find(__x) #define __profcxx_map2umap_destruct(__x...) \ __gnu_profile::__trace_map_to_unordered_map_destruct(__x) #else #define __profcxx_map2umap_construct(__x...) 0 #define __profcxx_map2umap_insert(__x...) #define __profcxx_map2umap_erase(__x...) #define __profcxx_map2umap_iterate(__x...) #define __profcxx_map2umap_invalidate(__x...) #define __profcxx_map2umap_find(__x...) #define __profcxx_map2umap_destruct(__x...) #endif // Set default values for compile-time customizable variables. #ifndef _GLIBCXX_PROFILE_TRACE_PATH_ROOT #define _GLIBCXX_PROFILE_TRACE_PATH_ROOT "libstdcxx-profile" #endif #ifndef _GLIBCXX_PROFILE_TRACE_ENV_VAR #define _GLIBCXX_PROFILE_TRACE_ENV_VAR "_GLIBCXX_PROFILE_TRACE_PATH_ROOT" #endif #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR #define _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR \ "_GLIBCXX_PROFILE_MAX_WARN_COUNT" #endif #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT #define _GLIBCXX_PROFILE_MAX_WARN_COUNT 10 #endif #ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH #define _GLIBCXX_PROFILE_MAX_STACK_DEPTH 32 #endif #ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR #define _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR \ "_GLIBCXX_PROFILE_MAX_STACK_DEPTH" #endif #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC (1 << 28) #endif #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR \ "_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC" #endif // Instrumentation hook implementations. #include "profile/impl/profiler_hash_func.h" #include "profile/impl/profiler_hashtable_size.h" #include "profile/impl/profiler_map_to_unordered_map.h" #include "profile/impl/profiler_vector_size.h" #include "profile/impl/profiler_vector_to_list.h" #include "profile/impl/profiler_list_to_slist.h" #include "profile/impl/profiler_list_to_vector.h" #endif // _GLIBCXX_PROFILE_PROFILER_H 8/profile/impl/profiler_vector_size.h000064400000005560152526447520013745 0ustar00// -*- C++ -*- // // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/impl/profiler_vector_size.h * @brief Collection of vector size traces. */ // Written by Lixia Liu and Silvius Rus. #ifndef _GLIBCXX_PROFILE_PROFILER_VECTOR_SIZE_H #define _GLIBCXX_PROFILE_PROFILER_VECTOR_SIZE_H 1 #include "profile/impl/profiler.h" #include "profile/impl/profiler_node.h" #include "profile/impl/profiler_trace.h" #include "profile/impl/profiler_state.h" #include "profile/impl/profiler_container_size.h" namespace __gnu_profile { /** @brief Hashtable size instrumentation trace producer. */ class __trace_vector_size : public __trace_container_size { public: __trace_vector_size() : __trace_container_size() { __id = "vector-size"; } }; inline void __trace_vector_size_init() { _GLIBCXX_PROFILE_DATA(_S_vector_size) = new __trace_vector_size(); } inline void __trace_vector_size_free() { delete _GLIBCXX_PROFILE_DATA(_S_vector_size); } inline void __trace_vector_size_report(FILE* __f, __warning_vector_t& __warnings) { __trace_report(_GLIBCXX_PROFILE_DATA(_S_vector_size), __f, __warnings); } inline __container_size_info* __trace_vector_size_construct(std::size_t __num) { if (!__profcxx_init()) return 0; if (!__reentrance_guard::__get_in()) return 0; __reentrance_guard __get_out; return _GLIBCXX_PROFILE_DATA(_S_vector_size)-> __insert(__get_stack(), __num); } inline void __trace_vector_size_resize(__container_size_info* __obj_info, std::size_t __from, std::size_t __to) { if (!__obj_info) return; __obj_info->__resize(__from, __to); } inline void __trace_vector_size_destruct(__container_size_info* __obj_info, std::size_t __num, std::size_t __inum) { if (!__obj_info) return; _GLIBCXX_PROFILE_DATA(_S_vector_size)-> __destruct(__obj_info, __num, __inum); } } // namespace __gnu_profile #endif /* _GLIBCXX_PROFILE_PROFILER_VECTOR_SIZE_H */ 8/profile/unordered_base.h000064400000021634152526447520011527 0ustar00// Profiling unordered containers implementation details -*- C++ -*- // Copyright (C) 2013-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/unordered_base.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_UNORDERED #define _GLIBCXX_PROFILE_UNORDERED 1 namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { template struct _Bucket_index_helper; template struct _Bucket_index_helper<_UnorderedCont, _Value, true> { static std::size_t bucket(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, true>* __node) { return __node->_M_hash_code % __uc.bucket_count(); } }; template struct _Bucket_index_helper<_UnorderedCont, _Value, false> { static std::size_t bucket(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, false>* __node) { return __uc.bucket(__node->_M_v()); } }; template struct _Bucket_index_helper<_UnorderedCont, std::pair, false> { typedef std::pair _Value; static std::size_t bucket(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, false>* __node) { return __uc.bucket(__node->_M_v().first); } }; template std::size_t __get_bucket_index(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, _Cache_hash_code>* __node) { using __bucket_index_helper = _Bucket_index_helper<_UnorderedCont, _Value, _Cache_hash_code>; return __bucket_index_helper::bucket(__uc, __node); } template struct _Equal_helper; template struct _Equal_helper<_UnorderedCont, _Value, true> { static std::size_t are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, true>* __lhs, const __detail::_Hash_node<_Value, true>* __rhs) { return __lhs->_M_hash_code == __rhs->_M_hash_code && __uc.key_eq()(__lhs->_M_v(), __rhs->_M_v()); } }; template struct _Equal_helper<_UnorderedCont, _Value, false> { static std::size_t are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, false>* __lhs, const __detail::_Hash_node<_Value, false>* __rhs) { return __uc.key_eq()(__lhs->_M_v(), __rhs->_M_v()); } }; template struct _Equal_helper<_UnorderedCont, std::pair, true> { typedef std::pair _Value; static std::size_t are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, true>* __lhs, const __detail::_Hash_node<_Value, true>* __rhs) { return __lhs->_M_hash_code == __rhs->_M_hash_code && __uc.key_eq()(__lhs->_M_v().first, __rhs->_M_v().first); } }; template struct _Equal_helper<_UnorderedCont, std::pair, false> { typedef std::pair _Value; static std::size_t are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, false>* __lhs, const __detail::_Hash_node<_Value, false>* __rhs) { return __uc.key_eq()(__lhs->_M_v().first, __rhs->_M_v().first); } }; template bool __are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, _Cache_hash_code>* __lhs, const __detail::_Hash_node<_Value, _Cache_hash_code>* __rhs) { using __equal_helper = _Equal_helper<_UnorderedCont, _Value, _Cache_hash_code>; return __equal_helper::are_equal(__uc, __lhs, __rhs); } template class _Unordered_profile { _UnorderedCont& _M_conjure() { return *(static_cast<_UnorderedCont*>(this)); } using __unique_keys = std::integral_constant; protected: _Unordered_profile() noexcept { _M_profile_construct(); } _Unordered_profile(const _Unordered_profile&) noexcept : _Unordered_profile() { } _Unordered_profile(_Unordered_profile&& __other) noexcept : _Unordered_profile() { _M_swap(__other); } ~_Unordered_profile() { _M_profile_destruct(); } _Unordered_profile& operator=(const _Unordered_profile&) noexcept { // Assignment just reset profiling. _M_profile_destruct(); _M_profile_construct(); } _Unordered_profile& operator=(_Unordered_profile&& __other) noexcept { // Take profiling of the moved instance... _M_swap(__other); // ...and then reset other instance profiling. __other._M_profile_destruct(); __other._M_profile_construct(); } void _M_profile_construct() noexcept { auto& __uc = _M_conjure(); _M_size_info = __profcxx_hashtable_size_construct(__uc.bucket_count()); _M_hashfunc_info = __profcxx_hash_func_construct(); } void _M_profile_destruct() noexcept { auto& __uc = _M_conjure(); __profcxx_hashtable_size_destruct(_M_size_info, __uc.bucket_count(), __uc.size()); _M_size_info = 0; if (!_M_hashfunc_info) return; _M_profile_destruct(__unique_keys()); _M_hashfunc_info = 0; } void _M_swap(_Unordered_profile& __other) noexcept { std::swap(_M_size_info, __other._M_size_info); std::swap(_M_hashfunc_info, __other._M_hashfunc_info); } void _M_profile_resize(std::size_t __old_size) { auto __new_size = _M_conjure().bucket_count(); if (__old_size != __new_size) __profcxx_hashtable_size_resize(_M_size_info, __old_size, __new_size); } __gnu_profile::__container_size_info* _M_size_info; __gnu_profile::__hashfunc_info* _M_hashfunc_info; private: void _M_profile_destruct(std::true_type); void _M_profile_destruct(std::false_type); }; template void _Unordered_profile<_UnorderedCont, _Unique_keys>:: _M_profile_destruct(std::true_type) { auto& __uc = _M_conjure(); std::size_t __hops = 0, __lc = 0, __chain = 0; auto __it = __uc.begin(); while (__it != __uc.end()) { auto __bkt = __get_bucket_index(__uc, __it._M_cur); auto __lit = __uc.begin(__bkt); auto __lend = __uc.end(__bkt); for (++__it, ++__lit; __lit != __lend; ++__it, ++__lit) ++__chain; if (__chain) { ++__chain; __lc = __lc > __chain ? __lc : __chain; __hops += __chain * (__chain - 1) / 2; __chain = 0; } } __profcxx_hash_func_destruct(_M_hashfunc_info, __lc, __uc.size(), __hops); } template void _Unordered_profile<_UnorderedCont, _Unique_keys>:: _M_profile_destruct(std::false_type) { auto& __uc = _M_conjure(); std::size_t __hops = 0, __lc = 0, __chain = 0, __unique_size = 0; auto __it = __uc.begin(); while (__it != __uc.end()) { auto __bkt = __get_bucket_index(__uc, __it._M_cur); auto __lit = __uc.begin(__bkt); auto __lend = __uc.end(__bkt); auto __pit = __it; ++__unique_size; for (++__it, ++__lit; __lit != __lend; ++__it, ++__lit) { if (!__are_equal(__uc, __pit._M_cur, __it._M_cur)) { ++__chain; ++__unique_size; __pit = __it; } } if (__chain) { ++__chain; __lc = __lc > __chain ? __lc : __chain; __hops += __chain * (__chain - 1) / 2; __chain = 0; } } __profcxx_hash_func_destruct(_M_hashfunc_info, __lc, __unique_size, __hops); } } // namespace __profile } // namespace std #endif 8/profile/iterator_tracker.h000064400000022522152526447520012107 0ustar00// Profiling iterator implementation -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file profile/iterator_tracker.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_ITERATOR_TRACKER #define _GLIBCXX_PROFILE_ITERATOR_TRACKER 1 #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { template class __iterator_tracker { typedef __iterator_tracker _Self; // The underlying iterator _Iterator _M_current; // The underlying data structure const _Sequence* _M_ds; typedef std::iterator_traits<_Iterator> _Traits; public: typedef _Iterator _Base_iterator; typedef typename _Traits::iterator_category iterator_category; typedef typename _Traits::value_type value_type; typedef typename _Traits::difference_type difference_type; typedef typename _Traits::reference reference; typedef typename _Traits::pointer pointer; __iterator_tracker() _GLIBCXX_NOEXCEPT : _M_current(), _M_ds(0) { } __iterator_tracker(const _Iterator& __i, const _Sequence* __seq) _GLIBCXX_NOEXCEPT : _M_current(__i), _M_ds(__seq) { } __iterator_tracker(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT : _M_current(__x._M_current), _M_ds(__x._M_ds) { } template __iterator_tracker(const __iterator_tracker<_MutableIterator, typename __gnu_cxx::__enable_if <(std::__are_same<_MutableIterator, typename _Sequence::iterator::_Base_iterator>::__value), _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT : _M_current(__x.base()), _M_ds(__x._M_get_sequence()) { } _Iterator base() const _GLIBCXX_NOEXCEPT { return _M_current; } /** * @brief Conversion to underlying non-debug iterator to allow * better interaction with non-profile containers. */ operator _Iterator() const _GLIBCXX_NOEXCEPT { return _M_current; } pointer operator->() const _GLIBCXX_NOEXCEPT { return &*_M_current; } __iterator_tracker& operator++() _GLIBCXX_NOEXCEPT { _M_ds->_M_profile_iterate(); ++_M_current; return *this; } __iterator_tracker operator++(int) _GLIBCXX_NOEXCEPT { _M_ds->_M_profile_iterate(); __iterator_tracker __tmp(*this); ++_M_current; return __tmp; } __iterator_tracker& operator--() _GLIBCXX_NOEXCEPT { _M_ds->_M_profile_iterate(1); --_M_current; return *this; } __iterator_tracker operator--(int) _GLIBCXX_NOEXCEPT { _M_ds->_M_profile_iterate(1); __iterator_tracker __tmp(*this); --_M_current; return __tmp; } __iterator_tracker& operator=(const __iterator_tracker& __x) _GLIBCXX_NOEXCEPT { _M_current = __x._M_current; _M_ds = __x._M_ds; return *this; } reference operator*() const _GLIBCXX_NOEXCEPT { return *_M_current; } // ------ Random access iterator requirements ------ reference operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT { return _M_current[__n]; } __iterator_tracker& operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT { _M_current += __n; return *this; } __iterator_tracker operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT { __iterator_tracker __tmp(*this); __tmp += __n; return __tmp; } __iterator_tracker& operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT { _M_current += -__n; return *this; } __iterator_tracker operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT { __iterator_tracker __tmp(*this); __tmp -= __n; return __tmp; } const _Sequence* _M_get_sequence() const { return static_cast(_M_ds); } }; template inline bool operator==(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() == __rhs.base(); } template inline bool operator==(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() == __rhs.base(); } template inline bool operator!=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() != __rhs.base(); } template inline bool operator!=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() != __rhs.base(); } template inline bool operator<(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() < __rhs.base(); } template inline bool operator<(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() < __rhs.base(); } template inline bool operator<=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() <= __rhs.base(); } template inline bool operator<=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() <= __rhs.base(); } template inline bool operator>(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() > __rhs.base(); } template inline bool operator>(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() > __rhs.base(); } template inline bool operator>=(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() >= __rhs.base(); } template inline bool operator>=(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() >= __rhs.base(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // According to the resolution of DR179 not only the various comparison // operators but also operator- must accept mixed iterator/const_iterator // parameters. template inline typename __iterator_tracker<_IteratorL, _Sequence>::difference_type operator-(const __iterator_tracker<_IteratorL, _Sequence>& __lhs, const __iterator_tracker<_IteratorR, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() - __rhs.base(); } template inline typename __iterator_tracker<_Iterator, _Sequence>::difference_type operator-(const __iterator_tracker<_Iterator, _Sequence>& __lhs, const __iterator_tracker<_Iterator, _Sequence>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() - __rhs.base(); } template inline __iterator_tracker<_Iterator, _Sequence> operator+(typename __iterator_tracker<_Iterator,_Sequence>::difference_type __n, const __iterator_tracker<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT { return __i + __n; } } // namespace __profile } // namespace std #endif 8/profile/set.h000064400000043311152526447520007335 0ustar00// Profiling set implementation -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file profile/set.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_SET_H #define _GLIBCXX_PROFILE_SET_H 1 #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::set wrapper with performance instrumentation. template, typename _Allocator = std::allocator<_Key> > class set : public _GLIBCXX_STD_C::set<_Key,_Compare,_Allocator>, public _Ordered_profile > { typedef _GLIBCXX_STD_C::set<_Key, _Compare, _Allocator> _Base; typedef typename _Base::iterator _Base_iterator; typedef typename _Base::const_iterator _Base_const_iterator; public: // types: typedef _Key key_type; typedef _Key value_type; typedef _Compare key_compare; typedef _Compare value_compare; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __iterator_tracker<_Base_iterator, set> iterator; typedef __iterator_tracker<_Base_const_iterator, set> const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef typename _Base::size_type size_type; typedef typename _Base::difference_type difference_type; // 23.3.3.1 construct/copy/destroy: #if __cplusplus < 201103L set() : _Base() { } set(const set& __x) : _Base(__x) { } ~set() { } #else set() = default; set(const set&) = default; set(set&&) = default; ~set() = default; #endif explicit set(const _Compare& __comp, const _Allocator& __a = _Allocator()) : _Base(__comp, __a) { } #if __cplusplus >= 201103L template> #else template #endif set(_InputIterator __first, _InputIterator __last, const _Compare& __comp = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__first, __last, __comp, __a) { } #if __cplusplus >= 201103L set(initializer_list __l, const _Compare& __comp = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__l, __comp, __a) { } explicit set(const _Allocator& __a) : _Base(__a) { } set(const set& __x, const _Allocator& __a) : _Base(__x, __a) { } set(set&& __x, const _Allocator& __a) noexcept( noexcept(_Base(std::move(__x), __a)) ) : _Base(std::move(__x), __a) { } set(initializer_list __l, const _Allocator& __a) : _Base(__l, __a) { } template set(_InputIterator __first, _InputIterator __last, const _Allocator& __a) : _Base(__first, __last, __a) { } #endif set(const _Base& __x) : _Base(__x) { } #if __cplusplus < 201103L set& operator=(const set& __x) { this->_M_profile_destruct(); _M_base() = __x; this->_M_profile_construct(); return *this; } #else set& operator=(const set&) = default; set& operator=(set&&) = default; set& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } #endif // iterators iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::begin(), this); } iterator end() _GLIBCXX_NOEXCEPT { return iterator(_Base::end(), this); } const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::end(), this); } #if __cplusplus >= 201103L const_iterator cbegin() const noexcept { return const_iterator(_Base::cbegin(), this); } const_iterator cend() const noexcept { return const_iterator(_Base::cend(), this); } #endif reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L const_reverse_iterator crbegin() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cend()); } const_reverse_iterator crend() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cbegin()); } #endif void swap(set& __x) _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) { _Base::swap(__x); this->_M_swap(__x); } // modifiers: #if __cplusplus >= 201103L template std::pair emplace(_Args&&... __args) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); auto __base_ret = _Base::emplace(std::forward<_Args>(__args)...); return std::make_pair(iterator(__base_ret.first, this), __base_ret.second); } template iterator emplace_hint(const_iterator __pos, _Args&&... __args) { auto size_before = this->size(); auto __res = _Base::emplace_hint(__pos.base(), std::forward<_Args>(__args)...); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif std::pair insert(const value_type& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); std::pair<_Base_iterator, bool> __base_ret = _Base::insert(__x); return std::make_pair(iterator(__base_ret.first, this), __base_ret.second); } #if __cplusplus >= 201103L std::pair insert(value_type&& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); std::pair<_Base_iterator, bool> __base_ret = _Base::insert(std::move(__x)); return std::make_pair(iterator(__base_ret.first, this), __base_ret.second); } #endif iterator insert(const_iterator __pos, const value_type& __x) { size_type size_before = this->size(); _Base_iterator __res = _Base::insert(__pos.base(), __x); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #if __cplusplus >= 201103L iterator insert(const_iterator __pos, value_type&& __x) { return iterator(_Base::insert(__pos.base(), std::move(__x)), this); } #endif template void insert(_InputIterator __first, _InputIterator __last) { for (; __first != __last; ++__first) insert(*__first); } #if __cplusplus >= 201103L void insert(initializer_list __l) { insert(__l.begin(), __l.end()); } #endif #if __cplusplus >= 201103L iterator erase(const_iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::erase(__pos.base()), this); } #else void erase(iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); _Base::erase(__pos.base()); } #endif size_type erase(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return _Base::erase(__x); } #if __cplusplus >= 201103L iterator erase(const_iterator __first, const_iterator __last) { if (__first != __last) { iterator __ret; for (; __first != __last;) __ret = erase(__first++); return __ret; } return iterator(_Base::erase(__first.base(), __last.base()), this); } #else void erase(iterator __first, iterator __last) { for (; __first != __last;) erase(__first++); } #endif void clear() _GLIBCXX_NOEXCEPT { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } size_type count(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #if __cplusplus > 201103L template::type> size_type count(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #endif // set operations: iterator find(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return iterator(_Base::find(__x), this); } const_iterator find(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return const_iterator(_Base::find(__x), this); } #if __cplusplus > 201103L template::type> iterator find(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } template::type> const_iterator find(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } #endif iterator lower_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::lower_bound(__x), this); } const_iterator lower_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::lower_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator lower_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } template::type> const_iterator lower_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } #endif iterator upper_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::upper_bound(__x), this); } const_iterator upper_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::upper_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator upper_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } template::type> const_iterator upper_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } #endif std::pair equal_range(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_iterator, _Base_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(iterator(__base_ret.first, this), iterator(__base_ret.second, this)); } std::pair equal_range(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_const_iterator, _Base_const_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(const_iterator(__base_ret.first, this), const_iterator(__base_ret.second, this)); } #if __cplusplus > 201103L template::type> std::pair equal_range(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } template::type> std::pair equal_range(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } #endif _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } private: /** If hint is used we consider that the map and unordered_map * operations have equivalent insertion cost so we do not update metrics * about it. * Note that to find out if hint has been used is libstdc++ * implementation dependent. */ bool _M_hint_used(_Base_const_iterator __hint, _Base_iterator __res) { return (__hint == __res || (__hint == _M_base().end() && ++__res == _M_base().end()) || (__hint != _M_base().end() && (++__hint == __res || ++__res == --__hint))); } template friend bool operator==(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&); template friend bool operator<(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&); }; template inline bool operator==(const set<_Key, _Compare, _Allocator>& __lhs, const set<_Key, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() == __rhs._M_base(); } template inline bool operator<(const set<_Key, _Compare, _Allocator>& __lhs, const set<_Key, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() < __rhs._M_base(); } template inline bool operator!=(const set<_Key, _Compare, _Allocator>& __lhs, const set<_Key, _Compare, _Allocator>& __rhs) { return !(__lhs == __rhs); } template inline bool operator<=(const set<_Key, _Compare, _Allocator>& __lhs, const set<_Key, _Compare, _Allocator>& __rhs) { return !(__rhs < __lhs); } template inline bool operator>=(const set<_Key, _Compare, _Allocator>& __lhs, const set<_Key, _Compare, _Allocator>& __rhs) { return !(__lhs < __rhs); } template inline bool operator>(const set<_Key, _Compare, _Allocator>& __lhs, const set<_Key, _Compare, _Allocator>& __rhs) { return __rhs < __lhs; } template void swap(set<_Key, _Compare, _Allocator>& __x, set<_Key, _Compare, _Allocator>& __y) _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y))) { return __x.swap(__y); } } // namespace __profile } // namespace std #endif 8/profile/bitset000064400000014717152526447520007616 0ustar00// Profiling bitset implementation -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file profile/bitset * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_BITSET #define _GLIBCXX_PROFILE_BITSET #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::bitset wrapper with performance instrumentation, none at the /// moment. template class bitset : public _GLIBCXX_STD_C::bitset<_Nb> { typedef _GLIBCXX_STD_C::bitset<_Nb> _Base; public: // 23.3.5.1 constructors: #if __cplusplus < 201103L bitset() : _Base() { } #else constexpr bitset() = default; #endif #if __cplusplus >= 201103L constexpr bitset(unsigned long long __val) noexcept #else bitset(unsigned long __val) #endif : _Base(__val) { } template explicit bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str, typename std::basic_string<_CharT, _Traits, _Alloc>::size_type __pos = 0, typename std::basic_string<_CharT, _Traits, _Alloc>::size_type __n = (std::basic_string<_CharT, _Traits, _Alloc>::npos)) : _Base(__str, __pos, __n) { } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 396. what are characters zero and one. template bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str, typename std::basic_string<_CharT, _Traits, _Alloc>::size_type __pos, typename std::basic_string<_CharT, _Traits, _Alloc>::size_type __n, _CharT __zero, _CharT __one = _CharT('1')) : _Base(__str, __pos, __n, __zero, __one) { } bitset(const _Base& __x) : _Base(__x) { } #if __cplusplus >= 201103L template explicit bitset(const _CharT* __str, typename std::basic_string<_CharT>::size_type __n = std::basic_string<_CharT>::npos, _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) : _Base(__str, __n, __zero, __one) { } #endif // 23.3.5.2 bitset operations: bitset<_Nb>& operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT { _M_base() &= __rhs; return *this; } bitset<_Nb>& operator|=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT { _M_base() |= __rhs; return *this; } bitset<_Nb>& operator^=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT { _M_base() ^= __rhs; return *this; } bitset<_Nb>& operator<<=(size_t __pos) _GLIBCXX_NOEXCEPT { _M_base() <<= __pos; return *this; } bitset<_Nb>& operator>>=(size_t __pos) _GLIBCXX_NOEXCEPT { _M_base() >>= __pos; return *this; } bitset<_Nb>& set() _GLIBCXX_NOEXCEPT { _Base::set(); return *this; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 186. bitset::set() second parameter should be bool bitset<_Nb>& set(size_t __pos, bool __val = true) { _Base::set(__pos, __val); return *this; } bitset<_Nb>& reset() _GLIBCXX_NOEXCEPT { _Base::reset(); return *this; } bitset<_Nb>& reset(size_t __pos) { _Base::reset(__pos); return *this; } bitset<_Nb> operator~() const _GLIBCXX_NOEXCEPT { return bitset(~_M_base()); } bitset<_Nb>& flip() _GLIBCXX_NOEXCEPT { _Base::flip(); return *this; } bitset<_Nb>& flip(size_t __pos) { _Base::flip(__pos); return *this; } bool operator==(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT { return _M_base() == __rhs; } bool operator!=(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT { return _M_base() != __rhs; } bitset<_Nb> operator<<(size_t __pos) const _GLIBCXX_NOEXCEPT { return bitset<_Nb>(_M_base() << __pos); } bitset<_Nb> operator>>(size_t __pos) const _GLIBCXX_NOEXCEPT { return bitset<_Nb>(_M_base() >> __pos); } _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } }; template bitset<_Nb> operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT { return bitset<_Nb>(__x) &= __y; } template bitset<_Nb> operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT { return bitset<_Nb>(__x) |= __y; } template bitset<_Nb> operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT { return bitset<_Nb>(__x) ^= __y; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) { return __is >> __x._M_base(); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const bitset<_Nb>& __x) { return __os << __x._M_base(); } } // namespace __profile #if __cplusplus >= 201103L // DR 1182. /// std::hash specialization for bitset. template struct hash<__profile::bitset<_Nb>> : public __hash_base> { size_t operator()(const __profile::bitset<_Nb>& __b) const noexcept { return std::hash<_GLIBCXX_STD_C::bitset<_Nb>>()(__b._M_base()); } }; #endif } // namespace std #endif 8/profile/deque000064400000012231152526447520007414 0ustar00// Profiling deque implementation -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file profile/deque * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_DEQUE #define _GLIBCXX_PROFILE_DEQUE 1 #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::deque wrapper with performance instrumentation. template > class deque : public _GLIBCXX_STD_C::deque<_Tp, _Allocator> { typedef _GLIBCXX_STD_C::deque<_Tp, _Allocator> _Base; public: typedef typename _Base::size_type size_type; typedef typename _Base::value_type value_type; // 23.2.1.1 construct/copy/destroy: #if __cplusplus < 201103L deque() : _Base() { } deque(const deque& __x) : _Base(__x) { } ~deque() { } #else deque() = default; deque(const deque&) = default; deque(deque&&) = default; deque(const deque& __d, const _Allocator& __a) : _Base(__d, __a) { } deque(deque&& __d, const _Allocator& __a) : _Base(std::move(__d), __a) { } ~deque() = default; deque(initializer_list __l, const _Allocator& __a = _Allocator()) : _Base(__l, __a) { } #endif explicit deque(const _Allocator& __a) : _Base(__a) { } #if __cplusplus >= 201103L explicit deque(size_type __n, const _Allocator& __a = _Allocator()) : _Base(__n, __a) { } deque(size_type __n, const _Tp& __value, const _Allocator& __a = _Allocator()) : _Base(__n, __value, __a) { } #else explicit deque(size_type __n, const _Tp& __value = _Tp(), const _Allocator& __a = _Allocator()) : _Base(__n, __value, __a) { } #endif #if __cplusplus >= 201103L template> #else template #endif deque(_InputIterator __first, _InputIterator __last, const _Allocator& __a = _Allocator()) : _Base(__first, __last, __a) { } deque(const _Base& __x) : _Base(__x) { } #if __cplusplus < 201103L deque& operator=(const deque& __x) { _M_base() = __x; return *this; } #else deque& operator=(const deque&) = default; deque& operator=(deque&&) = default; deque& operator=(initializer_list __l) { _M_base() = __l; return *this; } #endif void swap(deque& __x) _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) { _Base::swap(__x); } _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } }; template inline bool operator==(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) { return __lhs._M_base() == __rhs._M_base(); } template inline bool operator!=(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) { return __lhs._M_base() != __rhs._M_base(); } template inline bool operator<(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) { return __lhs._M_base() < __rhs._M_base(); } template inline bool operator<=(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) { return __lhs._M_base() <= __rhs._M_base(); } template inline bool operator>=(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) { return __lhs._M_base() >= __rhs._M_base(); } template inline bool operator>(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs) { return __lhs._M_base() > __rhs._M_base(); } template inline void swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs) _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } } // namespace __profile } // namespace std #endif 8/profile/map000064400000002336152526447520007073 0ustar00// Profiling map/multimap implementation -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/map * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_MAP #define _GLIBCXX_PROFILE_MAP 1 #include #include #include #endif 8/profile/vector000064400000037012152526447520007617 0ustar00// Profiling vector implementation -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/vector * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_VECTOR #define _GLIBCXX_PROFILE_VECTOR 1 #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { template class _Vector_profile_pre { _Vector& _M_conjure() { return *static_cast<_Vector*>(this); } public: #if __cplusplus >= 201103L _Vector_profile_pre() = default; _Vector_profile_pre(const _Vector_profile_pre&) = default; _Vector_profile_pre(_Vector_profile_pre&&) = default; _Vector_profile_pre& operator=(const _Vector_profile_pre&) { _M_conjure()._M_profile_destruct(); } _Vector_profile_pre& operator=(_Vector_profile_pre&&) noexcept { _M_conjure()._M_profile_destruct(); } #endif }; template class _Vector_profile_post { _Vector& _M_conjure() { return *static_cast<_Vector*>(this); } protected: __gnu_profile::__container_size_info* _M_size_info; __gnu_profile::__vector2list_info* _M_vect2list_info; _Vector_profile_post() _GLIBCXX_NOEXCEPT { _M_profile_construct(); } #if __cplusplus >= 201103L _Vector_profile_post(const _Vector_profile_post&) noexcept : _Vector_profile_post() { } _Vector_profile_post(_Vector_profile_post&& __other) noexcept : _Vector_profile_post() { _M_swap(__other); } _Vector_profile_post& operator=(const _Vector_profile_post&) noexcept { _M_profile_construct(); } _Vector_profile_post& operator=(_Vector_profile_post&& __other) noexcept { _M_swap(__other); __other._M_profile_construct(); } #endif ~_Vector_profile_post() { _M_conjure()._M_profile_destruct(); } public: void _M_profile_construct() _GLIBCXX_NOEXCEPT { _M_size_info = __profcxx_vector_size_construct(_M_conjure().capacity()); _M_vect2list_info = __profcxx_vector2list_construct(); } void _M_profile_destruct() _GLIBCXX_NOEXCEPT { __profcxx_vector2list_destruct(_M_vect2list_info); _M_vect2list_info = 0; __profcxx_vector_size_destruct(_M_size_info, _M_conjure().capacity(), _M_conjure().size()); _M_size_info = 0; } void _M_swap(_Vector_profile_post& __other) _GLIBCXX_NOEXCEPT { std::swap(_M_size_info, __other._M_size_info); std::swap(_M_vect2list_info, __other._M_vect2list_info); } }; template > class vector : public _Vector_profile_pre >, public _GLIBCXX_STD_C::vector<_Tp, _Allocator>, public _Vector_profile_post > { typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base; typedef typename _Base::iterator _Base_iterator; typedef typename _Base::const_iterator _Base_const_iterator; public: typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __iterator_tracker<_Base_iterator, vector> iterator; typedef __iterator_tracker<_Base_const_iterator, vector> const_iterator; typedef typename _Base::size_type size_type; typedef typename _Base::difference_type difference_type; typedef _Tp value_type; typedef _Allocator allocator_type; typedef typename _Base::pointer pointer; typedef typename _Base::const_pointer const_pointer; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } // 23.2.4.1 construct/copy/destroy: #if __cplusplus < 201103L vector() { } vector(const vector& __x) : _Base(__x) { } #else vector() = default; vector(const vector&) = default; vector(vector&&) = default; #endif explicit vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT : _Base(__a) { } #if __cplusplus >= 201103L explicit vector(size_type __n, const _Allocator& __a = _Allocator()) : _Base(__n, __a) { } vector(size_type __n, const _Tp& __value, const _Allocator& __a = _Allocator()) : _Base(__n, __value, __a) { } #else explicit vector(size_type __n, const _Tp& __value = _Tp(), const _Allocator& __a = _Allocator()) : _Base(__n, __value, __a) { } #endif #if __cplusplus >= 201103L template> #else template #endif vector(_InputIterator __first, _InputIterator __last, const _Allocator& __a = _Allocator()) : _Base(__first, __last, __a) { } /// Construction from a normal-mode vector vector(const _Base& __x) : _Base(__x) { } #if __cplusplus >= 201103L vector(const _Base& __x, const _Allocator& __a) : _Base(__x, __a) { } vector(vector&& __x, const _Allocator& __a) : _Base(std::move(__x), __a) { } vector(initializer_list __l, const allocator_type& __a = allocator_type()) : _Base(__l, __a) { } #endif #if __cplusplus < 201103L vector& operator=(const vector& __x) { this->_M_profile_destruct(); _M_base() = __x; this->_M_profile_construct(); return *this; } #else vector& operator=(const vector&) = default; vector& operator=(vector&&) = default; vector& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } #endif // iterators: iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::begin(), this); } iterator end() _GLIBCXX_NOEXCEPT { return iterator(_Base::end(), this); } const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::end(), this); } reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L const_iterator cbegin() const noexcept { return const_iterator(_Base::begin(), this); } const_iterator cend() const noexcept { return const_iterator(_Base::end(), this); } const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } #endif // 23.2.4.2 capacity: #if __cplusplus >= 201103L void resize(size_type __sz) { __profcxx_vector2list_invalid_operator(this->_M_vect2list_info); _M_profile_resize(this->capacity(), __sz); _Base::resize(__sz); } void resize(size_type __sz, const _Tp& __c) { __profcxx_vector2list_invalid_operator(this->_M_vect2list_info); _M_profile_resize(this->capacity(), __sz); _Base::resize(__sz, __c); } #else void resize(size_type __sz, _Tp __c = _Tp()) { __profcxx_vector2list_invalid_operator(this->_M_vect2list_info); _M_profile_resize(this->capacity(), __sz); _Base::resize(__sz, __c); } #endif // element access: reference operator[](size_type __n) _GLIBCXX_NOEXCEPT { __profcxx_vector2list_invalid_operator(this->_M_vect2list_info); return _M_base()[__n]; } const_reference operator[](size_type __n) const _GLIBCXX_NOEXCEPT { __profcxx_vector2list_invalid_operator(this->_M_vect2list_info); return _M_base()[__n]; } // 23.2.4.3 modifiers: void push_back(const _Tp& __x) { size_type __old_size = this->capacity(); _Base::push_back(__x); _M_profile_resize(__old_size, this->capacity()); } #if __cplusplus >= 201103L void push_back(_Tp&& __x) { size_type __old_size = this->capacity(); _Base::push_back(std::move(__x)); _M_profile_resize(__old_size, this->capacity()); } #endif iterator #if __cplusplus >= 201103L insert(const_iterator __pos, const _Tp& __x) #else insert(iterator __pos, const _Tp& __x) #endif { __profcxx_vector2list_insert(this->_M_vect2list_info, __pos.base() - _Base::begin(), this->size()); size_type __old_size = this->capacity(); _Base_iterator __res = _Base::insert(__pos.base(), __x); _M_profile_resize(__old_size, this->capacity()); return iterator(__res, this); } #if __cplusplus >= 201103L iterator insert(const_iterator __pos, _Tp&& __x) { __profcxx_vector2list_insert(this->_M_vect2list_info, __pos.base() - _Base::cbegin(), this->size()); size_type __old_size = this->capacity(); _Base_iterator __res = _Base::insert(__pos.base(), __x); _M_profile_resize(__old_size, this->capacity()); return iterator(__res, this); } template iterator emplace(const_iterator __pos, _Args&&... __args) { _Base_iterator __res = _Base::emplace(__pos.base(), std::forward<_Args>(__args)...); return iterator(__res, this); } iterator insert(const_iterator __pos, initializer_list __l) { return this->insert(__pos, __l.begin(), __l.end()); } #endif void swap(vector& __x) #if __cplusplus >= 201103L noexcept( noexcept(declval<_Base>().swap(__x)) ) #endif { _Base::swap(__x); this->_M_swap(__x); } #if __cplusplus >= 201103L iterator insert(const_iterator __pos, size_type __n, const _Tp& __x) { __profcxx_vector2list_insert(this->_M_vect2list_info, __pos.base() - _Base::cbegin(), this->size()); size_type __old_size = this->capacity(); _Base_iterator __res = _Base::insert(__pos, __n, __x); _M_profile_resize(__old_size, this->capacity()); return iterator(__res, this); } #else void insert(iterator __pos, size_type __n, const _Tp& __x) { __profcxx_vector2list_insert(this->_M_vect2list_info, __pos.base() - _Base::begin(), this->size()); size_type __old_size = this->capacity(); _Base::insert(__pos, __n, __x); _M_profile_resize(__old_size, this->capacity()); } #endif #if __cplusplus >= 201103L template> iterator insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) { __profcxx_vector2list_insert(this->_M_vect2list_info, __pos.base() - _Base::cbegin(), this->size()); size_type __old_size = this->capacity(); _Base_iterator __res = _Base::insert(__pos, __first, __last); _M_profile_resize(__old_size, this->capacity()); return iterator(__res, this); } #else template void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { __profcxx_vector2list_insert(this->_M_vect2list_info, __pos.base() - _Base::begin(), this->size()); size_type __old_size = this->capacity(); _Base::insert(__pos, __first, __last); _M_profile_resize(__old_size, this->capacity()); } #endif iterator #if __cplusplus >= 201103L erase(const_iterator __pos) #else erase(iterator __pos) #endif { return iterator(_Base::erase(__pos.base()), this); } iterator #if __cplusplus >= 201103L erase(const_iterator __first, const_iterator __last) #else erase(iterator __first, iterator __last) #endif { return iterator(_Base::erase(__first.base(), __last.base()), this); } void clear() _GLIBCXX_NOEXCEPT { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } inline void _M_profile_iterate(int __rewind = 0) const { __profcxx_vector2list_iterate(this->_M_vect2list_info, __rewind); } private: void _M_profile_resize(size_type __old_size, size_type __new_size) { if (__old_size < __new_size) { __profcxx_vector_size_resize(this->_M_size_info, this->size(), __new_size); __profcxx_vector2list_resize(this->_M_vect2list_info, this->size(), __new_size); } } }; template inline bool operator==(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() == __rhs._M_base(); } template inline bool operator!=(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() != __rhs._M_base(); } template inline bool operator<(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() < __rhs._M_base(); } template inline bool operator<=(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() <= __rhs._M_base(); } template inline bool operator>=(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() >= __rhs._M_base(); } template inline bool operator>(const vector<_Tp, _Alloc>& __lhs, const vector<_Tp, _Alloc>& __rhs) { return __lhs._M_base() > __rhs._M_base(); } template inline void swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs) _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } } // namespace __profile #if __cplusplus >= 201103L // DR 1182. /// std::hash specialization for vector. template struct hash<__profile::vector> : public __hash_base> { size_t operator()(const __profile::vector& __b) const noexcept { return std::hash<_GLIBCXX_STD_C::vector>()(__b._M_base()); } }; #endif } // namespace std #endif 8/profile/forward_list000064400000014366152526447520011023 0ustar00// -*- C++ -*- // Copyright (C) 2010-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file profile/forward_list * This file is a GNU debug extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_FORWARD_LIST #define _GLIBCXX_PROFILE_FORWARD_LIST 1 #if __cplusplus < 201103L # include #else #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::forward_list wrapper with performance instrumentation. template > class forward_list : public _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> { typedef _GLIBCXX_STD_C::forward_list<_Tp, _Alloc> _Base; public: typedef typename _Base::size_type size_type; typedef typename _Base::const_iterator const_iterator; // 23.2.3.1 construct/copy/destroy: forward_list() = default; explicit forward_list(const _Alloc& __al) noexcept : _Base(__al) { } forward_list(const forward_list& __list, const _Alloc& __al) : _Base(__list, __al) { } forward_list(forward_list&& __list, const _Alloc& __al) : _Base(std::move(__list), __al) { } explicit forward_list(size_type __n, const _Alloc& __al = _Alloc()) : _Base(__n, __al) { } forward_list(size_type __n, const _Tp& __value, const _Alloc& __al = _Alloc()) : _Base(__n, __value, __al) { } template> forward_list(_InputIterator __first, _InputIterator __last, const _Alloc& __al = _Alloc()) : _Base(__first, __last, __al) { } forward_list(const forward_list&) = default; forward_list(forward_list&&) = default; forward_list(std::initializer_list<_Tp> __il, const _Alloc& __al = _Alloc()) : _Base(__il, __al) { } ~forward_list() = default; forward_list& operator=(const forward_list&) = default; forward_list& operator=(forward_list&&) = default; forward_list& operator=(std::initializer_list<_Tp> __il) { _M_base() = __il; return *this; } void swap(forward_list& __fl) noexcept( noexcept(declval<_Base&>().swap(__fl)) ) { _Base::swap(__fl); } void splice_after(const_iterator __pos, forward_list&& __fl) { _Base::splice_after(__pos, std::move(__fl)); } void splice_after(const_iterator __pos, forward_list& __list) { _Base::splice_after(__pos, __list); } void splice_after(const_iterator __pos, forward_list&& __list, const_iterator __i) { _Base::splice_after(__pos, std::move(__list), __i); } void splice_after(const_iterator __pos, forward_list& __list, const_iterator __i) { _Base::splice_after(__pos, __list, __i); } void splice_after(const_iterator __pos, forward_list&& __list, const_iterator __before, const_iterator __last) { _Base::splice_after(__pos, std::move(__list), __before, __last); } void splice_after(const_iterator __pos, forward_list& __list, const_iterator __before, const_iterator __last) { _Base::splice_after(__pos, __list, __before, __last); } void merge(forward_list&& __list) { _Base::merge(std::move(__list)); } void merge(forward_list& __list) { _Base::merge(__list); } template void merge(forward_list&& __list, _Comp __comp) { _Base::merge(std::move(__list), __comp); } template void merge(forward_list& __list, _Comp __comp) { _Base::merge(__list, __comp); } _Base& _M_base() noexcept { return *this; } const _Base& _M_base() const noexcept { return *this; } }; template inline bool operator==(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return __lx._M_base() == __ly._M_base(); } template inline bool operator<(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return __lx._M_base() < __ly._M_base(); } template inline bool operator!=(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return !(__lx == __ly); } /// Based on operator< template inline bool operator>(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return (__ly < __lx); } /// Based on operator< template inline bool operator>=(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return !(__lx < __ly); } /// Based on operator< template inline bool operator<=(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return !(__ly < __lx); } /// See std::forward_list::swap(). template inline void swap(forward_list<_Tp, _Alloc>& __lx, forward_list<_Tp, _Alloc>& __ly) noexcept(noexcept(__lx.swap(__ly))) { __lx.swap(__ly); } } // namespace __profile } // namespace std #endif // C++11 #endif 8/profile/map.h000064400000047204152526447520007324 0ustar00// Profiling map implementation -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/map.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_MAP_H #define _GLIBCXX_PROFILE_MAP_H 1 #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::map wrapper with performance instrumentation. template, typename _Allocator = std::allocator > > class map : public _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator>, public _Ordered_profile > { typedef _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator> _Base; typedef typename _Base::iterator _Base_iterator; typedef typename _Base::const_iterator _Base_const_iterator; public: // types: typedef _Key key_type; typedef _Tp mapped_type; typedef typename _Base::value_type value_type; typedef _Compare key_compare; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __iterator_tracker<_Base_iterator, map> iterator; typedef __iterator_tracker<_Base_const_iterator, map> const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef typename _Base::size_type size_type; typedef typename _Base::difference_type difference_type; // 23.3.1.1 construct/copy/destroy: #if __cplusplus < 201103L map() : _Base() { } map(const map& __x) : _Base(__x) { } ~map() { } #else map() = default; map(const map&) = default; map(map&&) = default; ~map() = default; #endif explicit map(const _Compare& __comp, const _Allocator& __a = _Allocator()) : _Base(__comp, __a) { } #if __cplusplus >= 201103L template> #else template #endif map(_InputIterator __first, _InputIterator __last, const _Compare& __comp = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__first, __last, __comp, __a) { } map(const _Base& __x) : _Base(__x) { } #if __cplusplus >= 201103L map(initializer_list __l, const _Compare& __c = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__l, __c, __a) { } explicit map(const _Allocator& __a) : _Base(__a) { } map(const map& __x, const _Allocator& __a) : _Base(__x, __a) { } map(map&& __x, const _Allocator& __a) noexcept( noexcept(_Base(std::move(__x), __a)) ) : _Base(std::move(__x), __a) { } map(initializer_list __l, const _Allocator& __a) : _Base(__l, __a) { } template map(_InputIterator __first, _InputIterator __last, const _Allocator& __a) : _Base(__first, __last, __a) { } #endif #if __cplusplus < 201103L map& operator=(const map& __x) { this->_M_profile_destruct(); _M_base() = __x; this->_M_profile_construct(); return *this; } #else map& operator=(const map&) = default; map& operator=(map&&) = default; map& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } #endif // iterators iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::begin(), this); } iterator end() _GLIBCXX_NOEXCEPT { return iterator(_Base::end(), this); } const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::end(), this); } #if __cplusplus >= 201103L const_iterator cbegin() const noexcept { return const_iterator(_Base::cbegin(), this); } const_iterator cend() const noexcept { return const_iterator(_Base::cend(), this); } #endif reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L const_reverse_iterator crbegin() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cend()); } const_reverse_iterator crend() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cbegin()); } #endif // 23.3.1.2 element access: mapped_type& operator[](const key_type& __k) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::operator[](__k); } #if __cplusplus >= 201103L mapped_type& operator[](key_type&& __k) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::operator[](std::move(__k)); } #endif mapped_type& at(const key_type& __k) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::at(__k); } const mapped_type& at(const key_type& __k) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::at(__k); } // modifiers: #if __cplusplus >= 201103L template std::pair emplace(_Args&&... __args) { // The cost is the same whether or not the element is inserted so we // always report insertion of 1 element. __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); auto __base_ret = _Base::emplace(std::forward<_Args>(__args)...); return std::make_pair(iterator(__base_ret.first, this), __base_ret.second); } template iterator emplace_hint(const_iterator __pos, _Args&&... __args) { auto size_before = this->size(); auto __res = _Base::emplace_hint(__pos.base(), std::forward<_Args>(__args)...); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif std::pair insert(const value_type& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); std::pair<_Base_iterator, bool> __base_ret = _Base::insert(__x); return std::make_pair(iterator(__base_ret.first, this), __base_ret.second); } #if __cplusplus >= 201103L template::value>::type> std::pair insert(_Pair&& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); auto __base_ret= _Base::insert(std::forward<_Pair>(__x)); return std::make_pair(iterator(__base_ret.first, this), __base_ret.second); } #endif #if __cplusplus >= 201103L void insert(std::initializer_list __list) { insert(__list.begin(), __list.end()); } #endif iterator #if __cplusplus >= 201103L insert(const_iterator __pos, const value_type& __x) #else insert(iterator __pos, const value_type& __x) #endif { size_type size_before = this->size(); _Base_iterator __res = _Base::insert(__pos.base(), __x); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #if __cplusplus >= 201103L template::value>::type> iterator insert(const_iterator __pos, _Pair&& __x) { size_type size_before = this->size(); auto __res = _Base::insert(__pos.base(), std::forward<_Pair>(__x)); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif template void insert(_InputIterator __first, _InputIterator __last) { for (; __first != __last; ++__first) insert(*__first); } #if __cplusplus >= 201103L iterator erase(const_iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::erase(__pos.base()), this); } iterator erase(iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::erase(__pos.base()), this); } #else void erase(iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); _Base::erase(__pos.base()); } #endif size_type erase(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return _Base::erase(__x); } #if __cplusplus >= 201103L iterator erase(const_iterator __first, const_iterator __last) { if (__first != __last) { iterator __ret; for (; __first != __last;) __ret = erase(__first++); return __ret; } else return iterator(_Base::erase(__first.base(), __last.base()), this); } #else void erase(iterator __first, iterator __last) { for (; __first != __last;) erase(__first++); } #endif void swap(map& __x) _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) { _Base::swap(__x); this->_M_swap(__x); } void clear() _GLIBCXX_NOEXCEPT { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } // 23.3.1.3 map operations: iterator find(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return iterator(_Base::find(__x), this); } #if __cplusplus > 201103L template::type> iterator find(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } #endif const_iterator find(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return const_iterator(_Base::find(__x), this); } #if __cplusplus > 201103L template::type> const_iterator find(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } #endif size_type count(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #if __cplusplus > 201103L template::type> size_type count(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #endif iterator lower_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::lower_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator lower_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } #endif const_iterator lower_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::lower_bound(__x), this); } #if __cplusplus > 201103L template::type> const_iterator lower_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } #endif iterator upper_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::upper_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator upper_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } #endif const_iterator upper_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::upper_bound(__x), this); } #if __cplusplus > 201103L template::type> const_iterator upper_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } #endif std::pair equal_range(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_iterator, _Base_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(iterator(__base_ret.first, this), iterator(__base_ret.second, this)); } #if __cplusplus > 201103L template::type> std::pair equal_range(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } #endif std::pair equal_range(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_const_iterator, _Base_const_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(const_iterator(__base_ret.first, this), const_iterator(__base_ret.second, this)); } #if __cplusplus > 201103L template::type> std::pair equal_range(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } #endif _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } private: /** If hint is used we consider that the map and unordered_map * operations have equivalent insertion cost so we do not update metrics * about it. * Note that to find out if hint has been used is libstdc++ * implementation dependent. */ bool _M_hint_used(_Base_const_iterator __hint, _Base_iterator __res) { return (__hint == __res || (__hint == _M_base().end() && ++__res == _M_base().end()) || (__hint != _M_base().end() && (++__hint == __res || ++__res == --__hint))); } template friend bool operator==(const map<_K1, _T1, _C1, _A1>&, const map<_K1, _T1, _C1, _A1>&); template friend bool operator<(const map<_K1, _T1, _C1, _A1>&, const map<_K1, _T1, _C1, _A1>&); }; template inline bool operator==(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, const map<_Key, _Tp, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() == __rhs._M_base(); } template inline bool operator<(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, const map<_Key, _Tp, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() < __rhs._M_base(); } template inline bool operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, const map<_Key, _Tp, _Compare, _Allocator>& __rhs) { return !(__lhs == __rhs); } template inline bool operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, const map<_Key, _Tp, _Compare, _Allocator>& __rhs) { return !(__rhs < __lhs); } template inline bool operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, const map<_Key, _Tp, _Compare, _Allocator>& __rhs) { return !(__lhs < __rhs); } template inline bool operator>(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, const map<_Key, _Tp, _Compare, _Allocator>& __rhs) { return __rhs < __lhs; } template inline void swap(map<_Key, _Tp, _Compare, _Allocator>& __lhs, map<_Key, _Tp, _Compare, _Allocator>& __rhs) _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } } // namespace __profile } // namespace std #endif 8/profile/unordered_set000064400000037643152526447520011171 0ustar00// Profiling unordered_set/unordered_multiset implementation -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/unordered_set * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_UNORDERED_SET #define _GLIBCXX_PROFILE_UNORDERED_SET 1 #if __cplusplus < 201103L # include #else # include #include #include #define _GLIBCXX_BASE unordered_set<_Key, _Hash, _Pred, _Alloc> #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /** @brief Unordered_set wrapper with performance instrumentation. */ template, typename _Pred = std::equal_to<_Key>, typename _Alloc = std::allocator<_Key> > class unordered_set : public _GLIBCXX_STD_BASE, public _Unordered_profile, true> { typedef _GLIBCXX_STD_BASE _Base; _Base& _M_base() noexcept { return *this; } const _Base& _M_base() const noexcept { return *this; } public: typedef typename _Base::size_type size_type; typedef typename _Base::hasher hasher; typedef typename _Base::key_equal key_equal; typedef typename _Base::allocator_type allocator_type; typedef typename _Base::key_type key_type; typedef typename _Base::value_type value_type; typedef typename _Base::difference_type difference_type; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef typename _Base::iterator iterator; typedef typename _Base::const_iterator const_iterator; unordered_set() = default; explicit unordered_set(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__n, __hf, __eql, __a) { } template unordered_set(_InputIterator __f, _InputIterator __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__f, __l, __n, __hf, __eql, __a) { } unordered_set(const unordered_set&) = default; unordered_set(const _Base& __x) : _Base(__x) { } unordered_set(unordered_set&&) = default; explicit unordered_set(const allocator_type& __a) : _Base(__a) { } unordered_set(const unordered_set& __uset, const allocator_type& __a) : _Base(__uset._M_base(), __a) { } unordered_set(unordered_set&& __uset, const allocator_type& __a) : _Base(std::move(__uset._M_base()), __a) { } unordered_set(initializer_list __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } unordered_set(size_type __n, const allocator_type& __a) : unordered_set(__n, hasher(), key_equal(), __a) { } unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__n, __hf, key_equal(), __a) { } template unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) { } template unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__first, __last, __n, __hf, key_equal(), __a) { } unordered_set(initializer_list __l, size_type __n, const allocator_type& __a) : unordered_set(__l, __n, hasher(), key_equal(), __a) { } unordered_set(initializer_list __l, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__l, __n, __hf, key_equal(), __a) { } unordered_set& operator=(const unordered_set&) = default; unordered_set& operator=(unordered_set&&) = default; unordered_set& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } void swap(unordered_set& __x) noexcept( noexcept(__x._M_base().swap(__x)) ) { _Base::swap(__x); this->_M_swap(__x); } void clear() noexcept { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } template std::pair emplace(_Args&&... __args) { size_type __old_size = _Base::bucket_count(); std::pair __res = _Base::emplace(std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } template iterator emplace_hint(const_iterator __it, _Args&&... __args) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } void insert(std::initializer_list __l) { size_type __old_size = _Base::bucket_count(); _Base::insert(__l); this->_M_profile_resize(__old_size); } std::pair insert(const value_type& __obj) { size_type __old_size = _Base::bucket_count(); std::pair __res = _Base::insert(__obj); this->_M_profile_resize(__old_size); return __res; } iterator insert(const_iterator __iter, const value_type& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, __v); this->_M_profile_resize(__old_size); return __res; } std::pair insert(value_type&& __obj) { size_type __old_size = _Base::bucket_count(); std::pair __res = _Base::insert(std::move(__obj)); this->_M_profile_resize(__old_size); return __res; } iterator insert(const_iterator __iter, value_type&& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, std::move(__v)); this->_M_profile_resize(__old_size); return __res; } template void insert(_InputIter __first, _InputIter __last) { size_type __old_size = _Base::bucket_count(); _Base::insert(__first, __last); this->_M_profile_resize(__old_size); } void rehash(size_type __n) { size_type __old_size = _Base::bucket_count(); _Base::rehash(__n); this->_M_profile_resize(__old_size); } }; template inline void swap(unordered_set<_Key, _Hash, _Pred, _Alloc>& __x, unordered_set<_Key, _Hash, _Pred, _Alloc>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template inline bool operator==(const unordered_set<_Key, _Hash, _Pred, _Alloc>& __x, const unordered_set<_Key, _Hash, _Pred, _Alloc>& __y) { return static_cast(__x) == __y; } template inline bool operator!=(const unordered_set<_Key, _Hash, _Pred, _Alloc>& __x, const unordered_set<_Key, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } #undef _GLIBCXX_BASE #undef _GLIBCXX_STD_BASE #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE #define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc> /** @brief Unordered_multiset wrapper with performance instrumentation. */ template, typename _Pred = std::equal_to<_Value>, typename _Alloc = std::allocator<_Value> > class unordered_multiset : public _GLIBCXX_STD_BASE, public _Unordered_profile, false> { typedef _GLIBCXX_STD_BASE _Base; _Base& _M_base() noexcept { return *this; } const _Base& _M_base() const noexcept { return *this; } public: typedef typename _Base::size_type size_type; typedef typename _Base::hasher hasher; typedef typename _Base::key_equal key_equal; typedef typename _Base::allocator_type allocator_type; typedef typename _Base::key_type key_type; typedef typename _Base::value_type value_type; typedef typename _Base::difference_type difference_type; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef typename _Base::iterator iterator; typedef typename _Base::const_iterator const_iterator; unordered_multiset() = default; explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__n, __hf, __eql, __a) { } template unordered_multiset(_InputIterator __f, _InputIterator __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__f, __l, __n, __hf, __eql, __a) { } unordered_multiset(const unordered_multiset&) = default; unordered_multiset(const _Base& __x) : _Base(__x) { } unordered_multiset(unordered_multiset&&) = default; explicit unordered_multiset(const allocator_type& __a) : _Base(__a) { } unordered_multiset(const unordered_multiset& __umset, const allocator_type& __a) : _Base(__umset._M_base(), __a) { } unordered_multiset(unordered_multiset&& __umset, const allocator_type& __a) : _Base(std::move(__umset._M_base()), __a) { } unordered_multiset(initializer_list __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } unordered_multiset(size_type __n, const allocator_type& __a) : unordered_multiset(__n, hasher(), key_equal(), __a) { } unordered_multiset(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__n, __hf, key_equal(), __a) { } template unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) { } template unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) { } unordered_multiset(initializer_list __l, size_type __n, const allocator_type& __a) : unordered_multiset(__l, __n, hasher(), key_equal(), __a) { } unordered_multiset(initializer_list __l, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__l, __n, __hf, key_equal(), __a) { } unordered_multiset& operator=(const unordered_multiset&) = default; unordered_multiset& operator=(unordered_multiset&&) = default; unordered_multiset& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } void swap(unordered_multiset& __x) noexcept( noexcept(__x._M_base().swap(__x)) ) { _Base::swap(__x); this->_M_swap(__x); } void clear() noexcept { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } template iterator emplace(_Args&&... __args) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::emplace(std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } template iterator emplace_hint(const_iterator __it, _Args&&... __args) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::emplace_hint(__it, std::forward<_Args>(__args)...); this->_M_profile_resize(__old_size); return __res; } void insert(std::initializer_list __l) { size_type __old_size = _Base::bucket_count(); _Base::insert(__l); this->_M_profile_resize(__old_size); } iterator insert(const value_type& __obj) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__obj); this->_M_profile_resize(__old_size); return __res; } iterator insert(const_iterator __iter, const value_type& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, __v); this->_M_profile_resize(__old_size); return __res; } iterator insert(value_type&& __obj) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(std::move(__obj)); this->_M_profile_resize(__old_size); return __res; } iterator insert(const_iterator __iter, value_type&& __v) { size_type __old_size = _Base::bucket_count(); iterator __res = _Base::insert(__iter, std::move(__v)); this->_M_profile_resize(__old_size); return __res; } template void insert(_InputIter __first, _InputIter __last) { size_type __old_size = _Base::bucket_count(); _Base::insert(__first, __last); this->_M_profile_resize(__old_size); } void rehash(size_type __n) { size_type __old_size = _Base::bucket_count(); _Base::rehash(__n); this->_M_profile_resize(__old_size); } }; template inline void swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template inline bool operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) { return static_cast(__x) == __y; } template inline bool operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } } // namespace __profile } // namespace std #undef _GLIBCXX_BASE #undef _GLIBCXX_STD_BASE #endif // C++11 #endif 8/profile/array000064400000021134152526447520007431 0ustar00// Profile array implementation -*- C++ -*- // Copyright (C) 2012-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file profile/array * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_PROFILE_ARRAY #define _GLIBCXX_PROFILE_ARRAY 1 #pragma GCC system_header #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { template struct array { typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef value_type* iterator; typedef const value_type* const_iterator; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; // Support for zero-sized arrays mandatory. typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type; typename _AT_Type::_Type _M_elems; // No explicit construct/copy/destroy for aggregate type. // DR 776. void fill(const value_type& __u) { std::fill_n(begin(), size(), __u); } void swap(array& __other) noexcept(_AT_Type::_Is_nothrow_swappable::value) { std::swap_ranges(begin(), end(), __other.begin()); } // Iterators. _GLIBCXX17_CONSTEXPR iterator begin() noexcept { return iterator(data()); } _GLIBCXX17_CONSTEXPR const_iterator begin() const noexcept { return const_iterator(data()); } _GLIBCXX17_CONSTEXPR iterator end() noexcept { return iterator(data() + _Nm); } _GLIBCXX17_CONSTEXPR const_iterator end() const noexcept { return const_iterator(data() + _Nm); } _GLIBCXX17_CONSTEXPR reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } _GLIBCXX17_CONSTEXPR const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } _GLIBCXX17_CONSTEXPR reverse_iterator rend() noexcept { return reverse_iterator(begin()); } _GLIBCXX17_CONSTEXPR const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } _GLIBCXX17_CONSTEXPR const_iterator cbegin() const noexcept { return const_iterator(data()); } _GLIBCXX17_CONSTEXPR const_iterator cend() const noexcept { return const_iterator(data() + _Nm); } _GLIBCXX17_CONSTEXPR const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } _GLIBCXX17_CONSTEXPR const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } // Capacity. constexpr size_type size() const noexcept { return _Nm; } constexpr size_type max_size() const noexcept { return _Nm; } constexpr bool empty() const noexcept { return size() == 0; } // Element access. reference operator[](size_type __n) noexcept { return _AT_Type::_S_ref(_M_elems, __n); } constexpr const_reference operator[](size_type __n) const noexcept { return _AT_Type::_S_ref(_M_elems, __n); } _GLIBCXX17_CONSTEXPR reference at(size_type __n) { if (__n >= _Nm) std::__throw_out_of_range_fmt(__N("array::at: __n " "(which is %zu) >= _Nm " "(which is %zu)"), __n, _Nm); return _AT_Type::_S_ref(_M_elems, __n); } constexpr const_reference at(size_type __n) const { // Result of conditional expression must be an lvalue so use // boolean ? lvalue : (throw-expr, lvalue) return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n) : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " ">= _Nm (which is %zu)"), __n, _Nm), _AT_Type::_S_ref(_M_elems, 0)); } _GLIBCXX17_CONSTEXPR reference front() noexcept { return *begin(); } constexpr const_reference front() const noexcept { return _AT_Type::_S_ref(_M_elems, 0); } _GLIBCXX17_CONSTEXPR reference back() noexcept { return _Nm ? *(end() - 1) : *end(); } constexpr const_reference back() const noexcept { return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1) : _AT_Type::_S_ref(_M_elems, 0); } _GLIBCXX17_CONSTEXPR pointer data() noexcept { return _AT_Type::_S_ptr(_M_elems); } _GLIBCXX17_CONSTEXPR const_pointer data() const noexcept { return _AT_Type::_S_ptr(_M_elems); } }; // Array comparisons. template inline bool operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return std::equal(__one.begin(), __one.end(), __two.begin()); } template inline bool operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return !(__one == __two); } template inline bool operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) { return std::lexicographical_compare(__a.begin(), __a.end(), __b.begin(), __b.end()); } template inline bool operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return __two < __one; } template inline bool operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return !(__one > __two); } template inline bool operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return !(__one < __two); } // Specialized algorithms. template inline void swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) noexcept(noexcept(__one.swap(__two))) { __one.swap(__two); } template constexpr _Tp& get(array<_Tp, _Nm>& __arr) noexcept { static_assert(_Int < _Nm, "index is out of bounds"); return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: _S_ref(__arr._M_elems, _Int); } template constexpr _Tp&& get(array<_Tp, _Nm>&& __arr) noexcept { static_assert(_Int < _Nm, "index is out of bounds"); return std::move(__profile::get<_Int>(__arr)); } template constexpr const _Tp& get(const array<_Tp, _Nm>& __arr) noexcept { static_assert(_Int < _Nm, "index is out of bounds"); return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: _S_ref(__arr._M_elems, _Int); } } // namespace __profile _GLIBCXX_BEGIN_NAMESPACE_VERSION // Tuple interface to class template array. /// tuple_size template struct tuple_size> : public integral_constant { }; /// tuple_element template struct tuple_element<_Int, std::__profile::array<_Tp, _Nm>> { static_assert(_Int < _Nm, "index is out of bounds"); typedef _Tp type; }; template struct __is_tuple_like_impl> : true_type { }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // _GLIBCXX_PROFILE_ARRAY 8/profile/list000064400000040736152526447520007277 0ustar00// Profiling list implementation -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file profile/list * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_LIST #define _GLIBCXX_PROFILE_LIST 1 #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { template class _List_profile { _List& _M_conjure() { return *static_cast<_List*>(this); } public: __gnu_profile::__list2slist_info* _M_list2slist_info; __gnu_profile::__list2vector_info* _M_list2vector_info; _List_profile() _GLIBCXX_NOEXCEPT { _M_profile_construct(); } void _M_profile_construct() _GLIBCXX_NOEXCEPT { _M_list2slist_info = __profcxx_list2slist_construct(); _M_list2vector_info = __profcxx_list2vector_construct(); } void _M_profile_destruct() _GLIBCXX_NOEXCEPT { __profcxx_list2vector_destruct(_M_list2vector_info); _M_list2vector_info = 0; __profcxx_list2slist_destruct(_M_list2slist_info); _M_list2slist_info = 0; } void _M_swap(_List_profile& __other) { std::swap(_M_list2slist_info, __other._M_list2slist_info); std::swap(_M_list2vector_info, __other._M_list2vector_info); } #if __cplusplus >= 201103L _List_profile(const _List_profile&) noexcept : _List_profile() { } _List_profile(_List_profile&& __other) noexcept : _List_profile() { _M_swap(__other); } _List_profile& operator=(const _List_profile&) noexcept { _M_profile_destruct(); _M_profile_construct(); } _List_profile& operator=(_List_profile&& __other) noexcept { _M_swap(__other); __other._M_profile_destruct(); __other._M_profile_construct(); } #endif ~_List_profile() { _M_profile_destruct(); } }; /** @brief List wrapper with performance instrumentation. */ template > class list : public _GLIBCXX_STD_C::list<_Tp, _Allocator>, public _List_profile > { typedef _GLIBCXX_STD_C::list<_Tp, _Allocator> _Base; public: typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __iterator_tracker iterator; typedef __iterator_tracker const_iterator; typedef typename _Base::size_type size_type; typedef typename _Base::difference_type difference_type; typedef _Tp value_type; typedef _Allocator allocator_type; typedef typename _Base::pointer pointer; typedef typename _Base::const_pointer const_pointer; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; // 23.2.2.1 construct/copy/destroy: #if __cplusplus < 201103L list() { } list(const list& __x) : _Base(__x) { } ~list() { } #else list() = default; list(const list&) = default; list(list&&) = default; ~list() = default; list(initializer_list __l, const allocator_type& __a = allocator_type()) : _Base(__l, __a) { } list(const list& __x, const allocator_type& __a) : _Base(__x, __a) { } list(list&& __x, const allocator_type& __a) : _Base(std::move(__x), __a) { } #endif explicit list(const _Allocator& __a) _GLIBCXX_NOEXCEPT : _Base(__a) { } #if __cplusplus >= 201103L explicit list(size_type __n, const allocator_type& __a = allocator_type()) : _Base(__n, __a) { } list(size_type __n, const _Tp& __value, const _Allocator& __a = _Allocator()) : _Base(__n, __value, __a) { } #else explicit list(size_type __n, const _Tp& __value = _Tp(), const _Allocator& __a = _Allocator()) : _Base(__n, __value, __a) { } #endif #if __cplusplus >= 201103L template> #else template #endif list(_InputIterator __first, _InputIterator __last, const _Allocator& __a = _Allocator()) : _Base(__first, __last, __a) { } list(const _Base& __x) : _Base(__x) { } #if __cplusplus < 201103L list& operator=(const list& __x) { this->_M_profile_destruct(); _M_base() = __x; this->_M_profile_construct(); return *this; } #else list& operator=(const list&) = default; list& operator=(list&&) = default; list& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } #endif // iterators: iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::begin(), this); } iterator end() _GLIBCXX_NOEXCEPT { __profcxx_list2slist_rewind(this->_M_list2slist_info); return iterator(_Base::end(), this); } const_iterator end() const _GLIBCXX_NOEXCEPT { __profcxx_list2slist_rewind(this->_M_list2slist_info); return const_iterator(_Base::end(), this); } reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { __profcxx_list2slist_rewind(this->_M_list2slist_info); return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { __profcxx_list2slist_rewind(this->_M_list2slist_info); return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L const_iterator cbegin() const noexcept { return const_iterator(_Base::cbegin(), this); } const_iterator cend() const noexcept { return const_iterator(_Base::cend(), this); } const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } #endif // 23.2.2.2 capacity: reference back() _GLIBCXX_NOEXCEPT { __profcxx_list2slist_rewind(this->_M_list2slist_info); return _Base::back(); } const_reference back() const _GLIBCXX_NOEXCEPT { __profcxx_list2slist_rewind(this->_M_list2slist_info); return _Base::back(); } // 23.2.2.3 modifiers: void push_front(const value_type& __x) { __profcxx_list2vector_invalid_operator(this->_M_list2vector_info); __profcxx_list2slist_operation(this->_M_list2slist_info); _Base::push_front(__x); } void pop_front() _GLIBCXX_NOEXCEPT { __profcxx_list2slist_operation(this->_M_list2slist_info); _Base::pop_front(); } void pop_back() _GLIBCXX_NOEXCEPT { _Base::pop_back(); __profcxx_list2slist_rewind(this->_M_list2slist_info); } #if __cplusplus >= 201103L template iterator emplace(const_iterator __position, _Args&&... __args) { return iterator(_Base::emplace(__position.base(), std::forward<_Args>(__args)...), this); } #endif iterator #if __cplusplus >= 201103L insert(const_iterator __pos, const _Tp& __x) #else insert(iterator __pos, const _Tp& __x) #endif { _M_profile_insert(__pos, this->size()); return iterator(_Base::insert(__pos.base(), __x), this); } #if __cplusplus >= 201103L iterator insert(const_iterator __pos, _Tp&& __x) { _M_profile_insert(__pos, this->size()); return iterator(_Base::emplace(__pos.base(), std::move(__x)), this); } iterator insert(const_iterator __pos, initializer_list __l) { _M_profile_insert(__pos, this->size()); return iterator(_Base::insert(__pos.base(), __l), this); } #endif #if __cplusplus >= 201103L iterator insert(const_iterator __pos, size_type __n, const _Tp& __x) { _M_profile_insert(__pos, this->size()); return iterator(_Base::insert(__pos.base(), __n, __x), this); } #else void insert(iterator __pos, size_type __n, const _Tp& __x) { _M_profile_insert(__pos, this->size()); _Base::insert(__pos.base(), __n, __x); } #endif #if __cplusplus >= 201103L template> iterator insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) { _M_profile_insert(__pos, this->size()); return iterator(_Base::insert(__pos.base(), __first, __last), this); } #else template void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { _M_profile_insert(__pos, this->size()); _Base::insert(__pos.base(), __first, __last); } #endif iterator #if __cplusplus >= 201103L erase(const_iterator __pos) noexcept #else erase(iterator __pos) #endif { return iterator(_Base::erase(__pos.base()), this); } iterator #if __cplusplus >= 201103L erase(const_iterator __pos, const_iterator __last) noexcept #else erase(iterator __pos, iterator __last) #endif { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 151. can't currently clear() empty container return iterator(_Base::erase(__pos.base(), __last.base()), this); } void swap(list& __x) _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) { _Base::swap(__x); this->_M_swap(__x); } void clear() _GLIBCXX_NOEXCEPT { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } // 23.2.2.4 list operations: void #if __cplusplus >= 201103L splice(const_iterator __pos, list&& __x) noexcept #else splice(iterator __pos, list& __x) #endif { this->splice(__pos, _GLIBCXX_MOVE(__x), __x.begin(), __x.end()); } #if __cplusplus >= 201103L void splice(const_iterator __pos, list& __x) noexcept { this->splice(__pos, std::move(__x)); } void splice(const_iterator __pos, list& __x, const_iterator __i) { this->splice(__pos, std::move(__x), __i); } #endif void #if __cplusplus >= 201103L splice(const_iterator __pos, list&& __x, const_iterator __i) noexcept #else splice(iterator __pos, list& __x, iterator __i) #endif { // We used to perform the splice_alloc check: not anymore, redundant // after implementing the relevant bits of N1599. // _GLIBCXX_RESOLVE_LIB_DEFECTS _Base::splice(__pos.base(), _GLIBCXX_MOVE(__x._M_base()), __i.base()); } void #if __cplusplus >= 201103L splice(const_iterator __pos, list&& __x, const_iterator __first, const_iterator __last) noexcept #else splice(iterator __pos, list& __x, iterator __first, iterator __last) #endif { _Base::splice(__pos.base(), _GLIBCXX_MOVE(__x._M_base()), __first.base(), __last.base()); } #if __cplusplus >= 201103L void splice(const_iterator __pos, list& __x, const_iterator __first, const_iterator __last) noexcept { this->splice(__pos, std::move(__x), __first, __last); } #endif void remove(const _Tp& __value) { for (iterator __x = begin(); __x != end(); ) { if (*__x == __value) __x = erase(__x); else ++__x; } } template void remove_if(_Predicate __pred) { for (iterator __x = begin(); __x != end(); ) { __profcxx_list2slist_operation(this->_M_list2slist_info); if (__pred(*__x)) __x = erase(__x); else ++__x; } } void unique() { iterator __first = begin(); iterator __last = end(); if (__first == __last) return; iterator __next = __first; while (++__next != __last) { __profcxx_list2slist_operation(this->_M_list2slist_info); if (*__first == *__next) erase(__next); else __first = __next; __next = __first; } } template void unique(_BinaryPredicate __binary_pred) { iterator __first = begin(); iterator __last = end(); if (__first == __last) return; iterator __next = __first; while (++__next != __last) { __profcxx_list2slist_operation(this->_M_list2slist_info); if (__binary_pred(*__first, *__next)) erase(__next); else __first = __next; __next = __first; } } void #if __cplusplus >= 201103L merge(list&& __x) #else merge(list& __x) #endif { _Base::merge(_GLIBCXX_MOVE(__x._M_base())); } #if __cplusplus >= 201103L void merge(list& __x) { this->merge(std::move(__x)); } #endif template void #if __cplusplus >= 201103L merge(list&& __x, _Compare __comp) #else merge(list& __x, _Compare __comp) #endif { _Base::merge(_GLIBCXX_MOVE(__x._M_base()), __comp); } #if __cplusplus >= 201103L template void merge(list& __x, _Compare __comp) { this->merge(std::move(__x), __comp); } #endif _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } void _M_profile_iterate(int __rewind = 0) const { __profcxx_list2slist_operation(this->_M_list2slist_info); __profcxx_list2vector_iterate(this->_M_list2vector_info, __rewind); if (__rewind) __profcxx_list2slist_rewind(this->_M_list2slist_info); } private: size_type _M_profile_insert(const_iterator __pos, size_type __size) { size_type __shift = 0; typename _Base::const_iterator __it = __pos.base(); for (; __it != _Base::end(); ++__it) __shift++; __profcxx_list2slist_rewind(this->_M_list2slist_info); __profcxx_list2slist_operation(this->_M_list2slist_info); __profcxx_list2vector_insert(this->_M_list2vector_info, __shift, __size); } }; template inline bool operator==(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) { return __lhs._M_base() == __rhs._M_base(); } template inline bool operator!=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) { return __lhs._M_base() != __rhs._M_base(); } template inline bool operator<(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) { return __lhs._M_base() < __rhs._M_base(); } template inline bool operator<=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) { return __lhs._M_base() <= __rhs._M_base(); } template inline bool operator>=(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) { return __lhs._M_base() >= __rhs._M_base(); } template inline bool operator>(const list<_Tp, _Alloc>& __lhs, const list<_Tp, _Alloc>& __rhs) { return __lhs._M_base() > __rhs._M_base(); } template inline void swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs) _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } } // namespace __profile } // namespace std #endif 8/profile/ordered_base.h000064400000005330152526447520011157 0ustar00// Profiling unordered containers implementation details -*- C++ -*- // Copyright (C) 2014-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/ordered_base.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_ORDERED #define _GLIBCXX_PROFILE_ORDERED 1 namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { template class _Ordered_profile { public: void _M_profile_iterate(int __rewind = 0) const { __profcxx_map2umap_iterate(this->_M_map2umap_info, __rewind); } protected: _Ordered_profile() _GLIBCXX_NOEXCEPT { _M_profile_construct(); } #if __cplusplus >= 201103L _Ordered_profile(const _Ordered_profile&) noexcept : _Ordered_profile() { } _Ordered_profile(_Ordered_profile&& __other) noexcept : _Ordered_profile() { _M_swap(__other); } _Ordered_profile& operator=(const _Ordered_profile&) noexcept { _M_profile_destruct(); _M_profile_construct(); } _Ordered_profile& operator=(_Ordered_profile&& __other) noexcept { _M_swap(__other); __other._M_profile_destruct(); __other._M_profile_construct(); } #endif ~_Ordered_profile() { _M_profile_destruct(); } void _M_profile_construct() _GLIBCXX_NOEXCEPT { _M_map2umap_info = __profcxx_map2umap_construct(); } void _M_profile_destruct() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_destruct(_M_map2umap_info); _M_map2umap_info = 0; } void _M_swap(_Ordered_profile& __other) { std::swap(_M_map2umap_info, __other._M_map2umap_info); } __gnu_profile::__map2umap_info* _M_map2umap_info; private: _Cont& _M_conjure() { return *static_cast<_Cont*>(this); } }; } // namespace __profile } // namespace std #endif 8/profile/base.h000064400000003255152526447520007457 0ustar00// -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . /** @file profile/base.h * @brief Sequential helper functions. * This file is a GNU profile extension to the Standard C++ Library. */ // Written by Lixia Liu #ifndef _GLIBCXX_PROFILE_BASE_H #define _GLIBCXX_PROFILE_BASE_H 1 #include // Profiling mode namespaces. /** * @namespace std::__profile * @brief GNU profile code, replaces standard behavior with profile behavior. */ namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { } } /** * @namespace __gnu_profile * @brief GNU profile code for public use. */ namespace __gnu_profile { // Import all the profile versions of components in namespace std. using namespace std::__profile; } #endif /* _GLIBCXX_PROFILE_BASE_H */ 8/profile/multiset.h000064400000044741152526447520010420 0ustar00// Profiling multiset implementation -*- C++ -*- // Copyright (C) 2009-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file profile/multiset.h * This file is a GNU profile extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PROFILE_MULTISET_H #define _GLIBCXX_PROFILE_MULTISET_H 1 #include #include namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { /// Class std::multiset wrapper with performance instrumentation. template, typename _Allocator = std::allocator<_Key> > class multiset : public _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator>, public _Ordered_profile > { typedef _GLIBCXX_STD_C::multiset<_Key, _Compare, _Allocator> _Base; typedef typename _Base::iterator _Base_iterator; typedef typename _Base::const_iterator _Base_const_iterator; public: // types: typedef _Key key_type; typedef _Key value_type; typedef _Compare key_compare; typedef _Compare value_compare; typedef _Allocator allocator_type; typedef typename _Base::reference reference; typedef typename _Base::const_reference const_reference; typedef __iterator_tracker<_Base_iterator, multiset> iterator; typedef __iterator_tracker<_Base_const_iterator, multiset> const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef typename _Base::size_type size_type; typedef typename _Base::difference_type difference_type; // 23.3.3.1 construct/copy/destroy: #if __cplusplus < 201103L multiset() : _Base() { } multiset(const multiset& __x) : _Base(__x) { } ~multiset() { } #else multiset() = default; multiset(const multiset&) = default; multiset(multiset&&) = default; ~multiset() = default; #endif explicit multiset(const _Compare& __comp, const _Allocator& __a = _Allocator()) : _Base(__comp, __a) { } #if __cplusplus >= 201103L template> #else template #endif multiset(_InputIterator __first, _InputIterator __last, const _Compare& __comp = _Compare(), const _Allocator& __a = _Allocator()) : _Base(__first, __last, __comp, __a) { } #if __cplusplus >= 201103L multiset(initializer_list __l, const _Compare& __comp = _Compare(), const allocator_type& __a = allocator_type()) : _Base(__l, __comp, __a) { } explicit multiset(const allocator_type& __a) : _Base(__a) { } multiset(const multiset& __x, const allocator_type& __a) : _Base(__x, __a) { } multiset(multiset&& __x, const allocator_type& __a) noexcept( noexcept(_Base(std::move(__x), __a)) ) : _Base(std::move(__x), __a) { } multiset(initializer_list __l, const allocator_type& __a) : _Base(__l, __a) { } template multiset(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : _Base(__first, __last, __a) { } #endif multiset(const _Base& __x) : _Base(__x) { } #if __cplusplus < 201103L multiset& operator=(const multiset& __x) { this->_M_profile_destruct(); _M_base() = __x; this->_M_profile_construct(); return *this; } #else multiset& operator=(const multiset&) = default; multiset& operator=(multiset&&) = default; multiset& operator=(initializer_list __l) { this->_M_profile_destruct(); _M_base() = __l; this->_M_profile_construct(); return *this; } #endif // iterators iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_Base::begin(), this); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::begin(), this); } iterator end() _GLIBCXX_NOEXCEPT { return iterator(_Base::end(), this); } const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(_Base::end(), this); } #if __cplusplus >= 201103L const_iterator cbegin() const noexcept { return const_iterator(_Base::cbegin(), this); } const_iterator cend() const noexcept { return const_iterator(_Base::cend(), this); } #endif reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L const_reverse_iterator crbegin() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cend()); } const_reverse_iterator crend() const noexcept { __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_reverse_iterator(cbegin()); } #endif void swap(multiset& __x) _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) { _Base::swap(__x); this->_M_swap(__x); } // modifiers: #if __cplusplus >= 201103L template iterator emplace(_Args&&... __args) { // The cost is the same whether or not the element is inserted so we // always report insertion of 1 element. __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::emplace(std::forward<_Args>(__args)...), this); } template iterator emplace_hint(const_iterator __pos, _Args&&... __args) { auto size_before = this->size(); auto __res = _Base::emplace_hint(__pos.base(), std::forward<_Args>(__args)...); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif iterator insert(const value_type& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::insert(__x), this); } #if __cplusplus >= 201103L iterator insert(value_type&& __x) { __profcxx_map2umap_insert(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::insert(std::move(__x)), this); } #endif iterator insert(const_iterator __pos, const value_type& __x) { size_type size_before = this->size(); _Base_iterator __res = _Base::insert(__pos.base(), __x); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #if __cplusplus >= 201103L iterator insert(const_iterator __pos, value_type&& __x) { auto size_before = this->size(); auto __res = _Base::insert(__pos.base(), std::move(__x)); __profcxx_map2umap_insert(this->_M_map2umap_info, size_before, _M_hint_used(__pos.base(), __res) ? 0 : 1); return iterator(__res, this); } #endif #if __cplusplus >= 201103L template> #else template #endif void insert(_InputIterator __first, _InputIterator __last) { for (; __first != __last; ++__first) insert(*__first); } #if __cplusplus >= 201103L void insert(initializer_list __l) { insert(__l.begin(), __l.end()); } #endif #if __cplusplus >= 201103L iterator erase(const_iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return iterator(_Base::erase(__pos.base()), this); } #else void erase(iterator __pos) { __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); _Base::erase(__pos.base()); } #endif size_type erase(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_erase(this->_M_map2umap_info, this->size(), 1); return _Base::erase(__x); } #if __cplusplus >= 201103L iterator erase(const_iterator __first, const_iterator __last) { if (__first != __last) { iterator __ret; for (; __first != __last;) __ret = erase(__first++); return __ret; } else return iterator(_Base::erase(__first.base(), __last.base()), this); } #else void erase(iterator __first, iterator __last) { for (; __first != __last;) erase(__first++); } #endif void clear() _GLIBCXX_NOEXCEPT { this->_M_profile_destruct(); _Base::clear(); this->_M_profile_construct(); } size_type count(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #if __cplusplus > 201103L template::type> size_type count(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return _Base::count(__x); } #endif // multiset operations: iterator find(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return iterator(_Base::find(__x), this); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 214. set::find() missing const overload const_iterator find(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return const_iterator(_Base::find(__x), this); } #if __cplusplus > 201103L template::type> iterator find(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } template::type> const_iterator find(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return { _Base::find(__x), this }; } #endif iterator lower_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); return iterator(_Base::lower_bound(__x), this); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 214. set::find() missing const overload const_iterator lower_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::lower_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator lower_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } template::type> const_iterator lower_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::lower_bound(__x), this }; } #endif iterator upper_bound(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return iterator(_Base::upper_bound(__x), this); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 214. set::find() missing const overload const_iterator upper_bound(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return const_iterator(_Base::upper_bound(__x), this); } #if __cplusplus > 201103L template::type> iterator upper_bound(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } template::type> const_iterator upper_bound(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); __profcxx_map2umap_invalidate(this->_M_map2umap_info); return { _Base::upper_bound(__x), this }; } #endif std::pair equal_range(const key_type& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_iterator, _Base_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(iterator(__base_ret.first, this), iterator(__base_ret.second, this)); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 214. set::find() missing const overload std::pair equal_range(const key_type& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); std::pair<_Base_const_iterator, _Base_const_iterator> __base_ret = _Base::equal_range(__x); return std::make_pair(const_iterator(__base_ret.first, this), const_iterator(__base_ret.second, this)); } #if __cplusplus > 201103L template::type> std::pair equal_range(const _Kt& __x) { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } template::type> std::pair equal_range(const _Kt& __x) const { __profcxx_map2umap_find(this->_M_map2umap_info, this->size()); auto __res = _Base::equal_range(__x); return { { __res.first, this }, { __res.second, this } }; } #endif _Base& _M_base() _GLIBCXX_NOEXCEPT { return *this; } const _Base& _M_base() const _GLIBCXX_NOEXCEPT { return *this; } private: /** If hint is used we consider that the map and unordered_map * operations have equivalent insertion cost so we do not update metrics * about it. * Note that to find out if hint has been used is libstdc++ * implementation dependent. */ bool _M_hint_used(_Base_const_iterator __hint, _Base_iterator __res) { return (__hint == __res || (__hint == _M_base().end() && ++__res == _M_base().end()) || (__hint != _M_base().end() && (++__hint == __res || ++__res == --__hint))); } template friend bool operator==(const multiset<_K1, _C1, _A1>&, const multiset<_K1, _C1, _A1>&); template friend bool operator< (const multiset<_K1, _C1, _A1>&, const multiset<_K1, _C1, _A1>&); }; template inline bool operator==(const multiset<_Key, _Compare, _Allocator>& __lhs, const multiset<_Key, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() == __rhs._M_base(); } template inline bool operator<(const multiset<_Key, _Compare, _Allocator>& __lhs, const multiset<_Key, _Compare, _Allocator>& __rhs) { __profcxx_map2umap_invalidate(__lhs._M_map2umap_info); __profcxx_map2umap_invalidate(__rhs._M_map2umap_info); return __lhs._M_base() < __rhs._M_base(); } template inline bool operator!=(const multiset<_Key, _Compare, _Allocator>& __lhs, const multiset<_Key, _Compare, _Allocator>& __rhs) { return !(__lhs == __rhs); } template inline bool operator<=(const multiset<_Key, _Compare, _Allocator>& __lhs, const multiset<_Key, _Compare, _Allocator>& __rhs) { return !(__rhs < __lhs); } template inline bool operator>=(const multiset<_Key, _Compare, _Allocator>& __lhs, const multiset<_Key, _Compare, _Allocator>& __rhs) { return !(__lhs < __rhs); } template inline bool operator>(const multiset<_Key, _Compare, _Allocator>& __lhs, const multiset<_Key, _Compare, _Allocator>& __rhs) { return __rhs < __lhs; } template void swap(multiset<_Key, _Compare, _Allocator>& __x, multiset<_Key, _Compare, _Allocator>& __y) _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y))) { return __x.swap(__y); } } // namespace __profile } // namespace std #endif 8/ccomplex000064400000002467152526447520006475 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/ccomplex * This is a Standard C++ Library header. */ #pragma GCC system_header #ifndef _GLIBCXX_CCOMPLEX #define _GLIBCXX_CCOMPLEX 1 #if __cplusplus < 201103L # include #endif extern "C++" { #include } #endif 8/cwctype000064400000005351152526447520006334 0ustar00// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/cwctype * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c wctype.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: // #pragma GCC system_header #include #if _GLIBCXX_HAVE_WCTYPE_H #if __GLIBC__ == 2 && __GLIBC_MINOR__ < 10 // Work around glibc BZ 9694 #include #endif #include #endif // _GLIBCXX_HAVE_WCTYPE_H #ifndef _GLIBCXX_CWCTYPE #define _GLIBCXX_CWCTYPE 1 // Get rid of those macros defined in in lieu of real functions. #undef iswalnum #undef iswalpha #if _GLIBCXX_HAVE_ISWBLANK # undef iswblank #endif #undef iswcntrl #undef iswctype #undef iswdigit #undef iswgraph #undef iswlower #undef iswprint #undef iswpunct #undef iswspace #undef iswupper #undef iswxdigit #undef towctrans #undef towlower #undef towupper #undef wctrans #undef wctype #if _GLIBCXX_USE_WCHAR_T namespace std { using ::wctrans_t; using ::wctype_t; using ::wint_t; using ::iswalnum; using ::iswalpha; #if _GLIBCXX_HAVE_ISWBLANK using ::iswblank; #endif using ::iswcntrl; using ::iswctype; using ::iswdigit; using ::iswgraph; using ::iswlower; using ::iswprint; using ::iswpunct; using ::iswspace; using ::iswupper; using ::iswxdigit; using ::towctrans; using ::towlower; using ::towupper; using ::wctrans; using ::wctype; } // namespace #endif //_GLIBCXX_USE_WCHAR_T #endif // _GLIBCXX_CWCTYPE 8/cstdalign000064400000002577152526447520006635 0ustar00// -*- C++ -*- // Copyright (C) 2011-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/cstdalign * This is a Standard C++ Library header. */ #pragma GCC system_header #ifndef _GLIBCXX_CSTDALIGN #define _GLIBCXX_CSTDALIGN 1 #if __cplusplus < 201103L # include #else # include # if _GLIBCXX_HAVE_STDALIGN_H # include # endif #endif #endif 8/locale000064400000002720152526447520006112 0ustar00// Locale support -*- C++ -*- // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // // ISO C++ 14882: 22.1 Locales // /** @file include/locale * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_LOCALE #define _GLIBCXX_LOCALE 1 #pragma GCC system_header #include #include #include #include #if __cplusplus >= 201103L # include #endif #endif /* _GLIBCXX_LOCALE */ 8/mutex000064400000043460152526447520006023 0ustar00// -*- C++ -*- // Copyright (C) 2003-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/mutex * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_MUTEX #define _GLIBCXX_MUTEX 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #if ! _GTHREAD_USE_MUTEX_TIMEDLOCK # include # include #endif #ifndef _GLIBCXX_HAVE_TLS # include #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @ingroup mutexes * @{ */ #ifdef _GLIBCXX_HAS_GTHREADS // Common base class for std::recursive_mutex and std::recursive_timed_mutex class __recursive_mutex_base { protected: typedef __gthread_recursive_mutex_t __native_type; __recursive_mutex_base(const __recursive_mutex_base&) = delete; __recursive_mutex_base& operator=(const __recursive_mutex_base&) = delete; #ifdef __GTHREAD_RECURSIVE_MUTEX_INIT __native_type _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT; __recursive_mutex_base() = default; #else __native_type _M_mutex; __recursive_mutex_base() { // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may) __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex); } ~__recursive_mutex_base() { __gthread_recursive_mutex_destroy(&_M_mutex); } #endif }; /// The standard recursive mutex type. class recursive_mutex : private __recursive_mutex_base { public: typedef __native_type* native_handle_type; recursive_mutex() = default; ~recursive_mutex() = default; recursive_mutex(const recursive_mutex&) = delete; recursive_mutex& operator=(const recursive_mutex&) = delete; void lock() { int __e = __gthread_recursive_mutex_lock(&_M_mutex); // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may) if (__e) __throw_system_error(__e); } bool try_lock() noexcept { // XXX EINVAL, EAGAIN, EBUSY return !__gthread_recursive_mutex_trylock(&_M_mutex); } void unlock() { // XXX EINVAL, EAGAIN, EBUSY __gthread_recursive_mutex_unlock(&_M_mutex); } native_handle_type native_handle() noexcept { return &_M_mutex; } }; #if _GTHREAD_USE_MUTEX_TIMEDLOCK template class __timed_mutex_impl { protected: typedef chrono::high_resolution_clock __clock_t; template bool _M_try_lock_for(const chrono::duration<_Rep, _Period>& __rtime) { using chrono::steady_clock; auto __rt = chrono::duration_cast(__rtime); if (ratio_greater()) ++__rt; return _M_try_lock_until(steady_clock::now() + __rt); } template bool _M_try_lock_until(const chrono::time_point<__clock_t, _Duration>& __atime) { auto __s = chrono::time_point_cast(__atime); auto __ns = chrono::duration_cast(__atime - __s); __gthread_time_t __ts = { static_cast(__s.time_since_epoch().count()), static_cast(__ns.count()) }; return static_cast<_Derived*>(this)->_M_timedlock(__ts); } template bool _M_try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { auto __rtime = __atime - _Clock::now(); return _M_try_lock_until(__clock_t::now() + __rtime); } }; /// The standard timed mutex type. class timed_mutex : private __mutex_base, public __timed_mutex_impl { public: typedef __native_type* native_handle_type; timed_mutex() = default; ~timed_mutex() = default; timed_mutex(const timed_mutex&) = delete; timed_mutex& operator=(const timed_mutex&) = delete; void lock() { int __e = __gthread_mutex_lock(&_M_mutex); // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may) if (__e) __throw_system_error(__e); } bool try_lock() noexcept { // XXX EINVAL, EAGAIN, EBUSY return !__gthread_mutex_trylock(&_M_mutex); } template bool try_lock_for(const chrono::duration<_Rep, _Period>& __rtime) { return _M_try_lock_for(__rtime); } template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { return _M_try_lock_until(__atime); } void unlock() { // XXX EINVAL, EAGAIN, EBUSY __gthread_mutex_unlock(&_M_mutex); } native_handle_type native_handle() noexcept { return &_M_mutex; } private: friend class __timed_mutex_impl; bool _M_timedlock(const __gthread_time_t& __ts) { return !__gthread_mutex_timedlock(&_M_mutex, &__ts); } }; /// recursive_timed_mutex class recursive_timed_mutex : private __recursive_mutex_base, public __timed_mutex_impl { public: typedef __native_type* native_handle_type; recursive_timed_mutex() = default; ~recursive_timed_mutex() = default; recursive_timed_mutex(const recursive_timed_mutex&) = delete; recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; void lock() { int __e = __gthread_recursive_mutex_lock(&_M_mutex); // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may) if (__e) __throw_system_error(__e); } bool try_lock() noexcept { // XXX EINVAL, EAGAIN, EBUSY return !__gthread_recursive_mutex_trylock(&_M_mutex); } template bool try_lock_for(const chrono::duration<_Rep, _Period>& __rtime) { return _M_try_lock_for(__rtime); } template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { return _M_try_lock_until(__atime); } void unlock() { // XXX EINVAL, EAGAIN, EBUSY __gthread_recursive_mutex_unlock(&_M_mutex); } native_handle_type native_handle() noexcept { return &_M_mutex; } private: friend class __timed_mutex_impl; bool _M_timedlock(const __gthread_time_t& __ts) { return !__gthread_recursive_mutex_timedlock(&_M_mutex, &__ts); } }; #else // !_GTHREAD_USE_MUTEX_TIMEDLOCK /// timed_mutex class timed_mutex { mutex _M_mut; condition_variable _M_cv; bool _M_locked = false; public: timed_mutex() = default; ~timed_mutex() { __glibcxx_assert( !_M_locked ); } timed_mutex(const timed_mutex&) = delete; timed_mutex& operator=(const timed_mutex&) = delete; void lock() { unique_lock __lk(_M_mut); _M_cv.wait(__lk, [&]{ return !_M_locked; }); _M_locked = true; } bool try_lock() { lock_guard __lk(_M_mut); if (_M_locked) return false; _M_locked = true; return true; } template bool try_lock_for(const chrono::duration<_Rep, _Period>& __rtime) { unique_lock __lk(_M_mut); if (!_M_cv.wait_for(__lk, __rtime, [&]{ return !_M_locked; })) return false; _M_locked = true; return true; } template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { unique_lock __lk(_M_mut); if (!_M_cv.wait_until(__lk, __atime, [&]{ return !_M_locked; })) return false; _M_locked = true; return true; } void unlock() { lock_guard __lk(_M_mut); __glibcxx_assert( _M_locked ); _M_locked = false; _M_cv.notify_one(); } }; /// recursive_timed_mutex class recursive_timed_mutex { mutex _M_mut; condition_variable _M_cv; thread::id _M_owner; unsigned _M_count = 0; // Predicate type that tests whether the current thread can lock a mutex. struct _Can_lock { // Returns true if the mutex is unlocked or is locked by _M_caller. bool operator()() const noexcept { return _M_mx->_M_count == 0 || _M_mx->_M_owner == _M_caller; } const recursive_timed_mutex* _M_mx; thread::id _M_caller; }; public: recursive_timed_mutex() = default; ~recursive_timed_mutex() { __glibcxx_assert( _M_count == 0 ); } recursive_timed_mutex(const recursive_timed_mutex&) = delete; recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; void lock() { auto __id = this_thread::get_id(); _Can_lock __can_lock{this, __id}; unique_lock __lk(_M_mut); _M_cv.wait(__lk, __can_lock); if (_M_count == -1u) __throw_system_error(EAGAIN); // [thread.timedmutex.recursive]/3 _M_owner = __id; ++_M_count; } bool try_lock() { auto __id = this_thread::get_id(); _Can_lock __can_lock{this, __id}; lock_guard __lk(_M_mut); if (!__can_lock()) return false; if (_M_count == -1u) return false; _M_owner = __id; ++_M_count; return true; } template bool try_lock_for(const chrono::duration<_Rep, _Period>& __rtime) { auto __id = this_thread::get_id(); _Can_lock __can_lock{this, __id}; unique_lock __lk(_M_mut); if (!_M_cv.wait_for(__lk, __rtime, __can_lock)) return false; if (_M_count == -1u) return false; _M_owner = __id; ++_M_count; return true; } template bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { auto __id = this_thread::get_id(); _Can_lock __can_lock{this, __id}; unique_lock __lk(_M_mut); if (!_M_cv.wait_until(__lk, __atime, __can_lock)) return false; if (_M_count == -1u) return false; _M_owner = __id; ++_M_count; return true; } void unlock() { lock_guard __lk(_M_mut); __glibcxx_assert( _M_owner == this_thread::get_id() ); __glibcxx_assert( _M_count > 0 ); if (--_M_count == 0) { _M_owner = {}; _M_cv.notify_one(); } } }; #endif #endif // _GLIBCXX_HAS_GTHREADS template inline unique_lock<_Lock> __try_to_lock(_Lock& __l) { return unique_lock<_Lock>{__l, try_to_lock}; } template struct __try_lock_impl { template static void __do_try_lock(tuple<_Lock&...>& __locks, int& __idx) { __idx = _Idx; auto __lock = std::__try_to_lock(std::get<_Idx>(__locks)); if (__lock.owns_lock()) { constexpr bool __cont = _Idx + 2 < sizeof...(_Lock); using __try_locker = __try_lock_impl<_Idx + 1, __cont>; __try_locker::__do_try_lock(__locks, __idx); if (__idx == -1) __lock.release(); } } }; template struct __try_lock_impl<_Idx, false> { template static void __do_try_lock(tuple<_Lock&...>& __locks, int& __idx) { __idx = _Idx; auto __lock = std::__try_to_lock(std::get<_Idx>(__locks)); if (__lock.owns_lock()) { __idx = -1; __lock.release(); } } }; /** @brief Generic try_lock. * @param __l1 Meets Lockable requirements (try_lock() may throw). * @param __l2 Meets Lockable requirements (try_lock() may throw). * @param __l3 Meets Lockable requirements (try_lock() may throw). * @return Returns -1 if all try_lock() calls return true. Otherwise returns * a 0-based index corresponding to the argument that returned false. * @post Either all arguments are locked, or none will be. * * Sequentially calls try_lock() on each argument. */ template int try_lock(_Lock1& __l1, _Lock2& __l2, _Lock3&... __l3) { int __idx; auto __locks = std::tie(__l1, __l2, __l3...); __try_lock_impl<0>::__do_try_lock(__locks, __idx); return __idx; } /** @brief Generic lock. * @param __l1 Meets Lockable requirements (try_lock() may throw). * @param __l2 Meets Lockable requirements (try_lock() may throw). * @param __l3 Meets Lockable requirements (try_lock() may throw). * @throw An exception thrown by an argument's lock() or try_lock() member. * @post All arguments are locked. * * All arguments are locked via a sequence of calls to lock(), try_lock() * and unlock(). If the call exits via an exception any locks that were * obtained will be released. */ template void lock(_L1& __l1, _L2& __l2, _L3&... __l3) { while (true) { using __try_locker = __try_lock_impl<0, sizeof...(_L3) != 0>; unique_lock<_L1> __first(__l1); int __idx; auto __locks = std::tie(__l2, __l3...); __try_locker::__do_try_lock(__locks, __idx); if (__idx == -1) { __first.release(); return; } } } #if __cplusplus >= 201703L #define __cpp_lib_scoped_lock 201703 /** @brief A scoped lock type for multiple lockable objects. * * A scoped_lock controls mutex ownership within a scope, releasing * ownership in the destructor. */ template class scoped_lock { public: explicit scoped_lock(_MutexTypes&... __m) : _M_devices(std::tie(__m...)) { std::lock(__m...); } explicit scoped_lock(adopt_lock_t, _MutexTypes&... __m) noexcept : _M_devices(std::tie(__m...)) { } // calling thread owns mutex ~scoped_lock() { std::apply([](_MutexTypes&... __m) { char __i[] __attribute__((__unused__)) = { (__m.unlock(), 0)... }; }, _M_devices); } scoped_lock(const scoped_lock&) = delete; scoped_lock& operator=(const scoped_lock&) = delete; private: tuple<_MutexTypes&...> _M_devices; }; template<> class scoped_lock<> { public: explicit scoped_lock() = default; explicit scoped_lock(adopt_lock_t) noexcept { } ~scoped_lock() = default; scoped_lock(const scoped_lock&) = delete; scoped_lock& operator=(const scoped_lock&) = delete; }; template class scoped_lock<_Mutex> { public: using mutex_type = _Mutex; explicit scoped_lock(mutex_type& __m) : _M_device(__m) { _M_device.lock(); } explicit scoped_lock(adopt_lock_t, mutex_type& __m) noexcept : _M_device(__m) { } // calling thread owns mutex ~scoped_lock() { _M_device.unlock(); } scoped_lock(const scoped_lock&) = delete; scoped_lock& operator=(const scoped_lock&) = delete; private: mutex_type& _M_device; }; #endif // C++17 #ifdef _GLIBCXX_HAS_GTHREADS /// once_flag struct once_flag { private: typedef __gthread_once_t __native_type; __native_type _M_once = __GTHREAD_ONCE_INIT; public: /// Constructor constexpr once_flag() noexcept = default; /// Deleted copy constructor once_flag(const once_flag&) = delete; /// Deleted assignment operator once_flag& operator=(const once_flag&) = delete; template friend void call_once(once_flag& __once, _Callable&& __f, _Args&&... __args); }; #ifdef _GLIBCXX_HAVE_TLS extern __thread void* __once_callable; extern __thread void (*__once_call)(); #else extern function __once_functor; extern void __set_once_functor_lock_ptr(unique_lock*); extern mutex& __get_once_mutex(); #endif extern "C" void __once_proxy(void); /// call_once template void call_once(once_flag& __once, _Callable&& __f, _Args&&... __args) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2442. call_once() shouldn't DECAY_COPY() auto __callable = [&] { std::__invoke(std::forward<_Callable>(__f), std::forward<_Args>(__args)...); }; #ifdef _GLIBCXX_HAVE_TLS __once_callable = std::__addressof(__callable); // NOLINT: PR 82481 __once_call = []{ (*(decltype(__callable)*)__once_callable)(); }; #else unique_lock __functor_lock(__get_once_mutex()); __once_functor = __callable; __set_once_functor_lock_ptr(&__functor_lock); #endif int __e = __gthread_once(&__once._M_once, &__once_proxy); #ifndef _GLIBCXX_HAVE_TLS if (__functor_lock) __set_once_functor_lock_ptr(0); #endif if (__e) __throw_system_error(__e); } #endif // _GLIBCXX_HAS_GTHREADS // @} group mutexes _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif // _GLIBCXX_MUTEX 8/stdexcept000064400000017447152526447520006672 0ustar00// Standard exception classes -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/stdexcept * This is a Standard C++ Library header. */ // // ISO C++ 19.1 Exception classes // #ifndef _GLIBCXX_STDEXCEPT #define _GLIBCXX_STDEXCEPT 1 #pragma GCC system_header #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if _GLIBCXX_USE_DUAL_ABI #if _GLIBCXX_USE_CXX11_ABI // Emulates an old COW string when the new std::string is in use. struct __cow_string { union { const char* _M_p; char _M_bytes[sizeof(const char*)]; }; __cow_string(); __cow_string(const std::string&); __cow_string(const char*, size_t); __cow_string(const __cow_string&) _GLIBCXX_USE_NOEXCEPT; __cow_string& operator=(const __cow_string&) _GLIBCXX_USE_NOEXCEPT; ~__cow_string(); #if __cplusplus >= 201103L __cow_string(__cow_string&&) noexcept; __cow_string& operator=(__cow_string&&) noexcept; #endif }; typedef basic_string __sso_string; #else // _GLIBCXX_USE_CXX11_ABI typedef basic_string __cow_string; // Emulates a new SSO string when the old std::string is in use. struct __sso_string { struct __str { const char* _M_p; size_t _M_string_length; char _M_local_buf[16]; }; union { __str _M_s; char _M_bytes[sizeof(__str)]; }; __sso_string() _GLIBCXX_USE_NOEXCEPT; __sso_string(const std::string&); __sso_string(const char*, size_t); __sso_string(const __sso_string&); __sso_string& operator=(const __sso_string&); ~__sso_string(); #if __cplusplus >= 201103L __sso_string(__sso_string&&) noexcept; __sso_string& operator=(__sso_string&&) noexcept; #endif }; #endif // _GLIBCXX_USE_CXX11_ABI #else // _GLIBCXX_USE_DUAL_ABI typedef basic_string __sso_string; typedef basic_string __cow_string; #endif /** * @addtogroup exceptions * @{ */ /** Logic errors represent problems in the internal logic of a program; * in theory, these are preventable, and even detectable before the * program runs (e.g., violations of class invariants). * @brief One of two subclasses of exception. */ class logic_error : public exception { __cow_string _M_msg; public: /** Takes a character string describing the error. */ explicit logic_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit logic_error(const char*) _GLIBCXX_TXN_SAFE; #endif #if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS logic_error(const logic_error&) _GLIBCXX_USE_NOEXCEPT; logic_error& operator=(const logic_error&) _GLIBCXX_USE_NOEXCEPT; #endif virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; /** Returns a C-style character string describing the general cause of * the current error (the same string passed to the ctor). */ virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; # ifdef _GLIBCXX_TM_TS_INTERNAL friend void* ::_txnal_logic_error_get_msg(void* e); # endif }; /** Thrown by the library, or by you, to report domain errors (domain in * the mathematical sense). */ class domain_error : public logic_error { public: explicit domain_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit domain_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~domain_error() _GLIBCXX_USE_NOEXCEPT; }; /** Thrown to report invalid arguments to functions. */ class invalid_argument : public logic_error { public: explicit invalid_argument(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit invalid_argument(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~invalid_argument() _GLIBCXX_USE_NOEXCEPT; }; /** Thrown when an object is constructed that would exceed its maximum * permitted size (e.g., a basic_string instance). */ class length_error : public logic_error { public: explicit length_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit length_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~length_error() _GLIBCXX_USE_NOEXCEPT; }; /** This represents an argument whose value is not within the expected * range (e.g., boundary checks in basic_string). */ class out_of_range : public logic_error { public: explicit out_of_range(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit out_of_range(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~out_of_range() _GLIBCXX_USE_NOEXCEPT; }; /** Runtime errors represent problems outside the scope of a program; * they cannot be easily predicted and can generally only be caught as * the program executes. * @brief One of two subclasses of exception. */ class runtime_error : public exception { __cow_string _M_msg; public: /** Takes a character string describing the error. */ explicit runtime_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit runtime_error(const char*) _GLIBCXX_TXN_SAFE; #endif #if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS runtime_error(const runtime_error&) _GLIBCXX_USE_NOEXCEPT; runtime_error& operator=(const runtime_error&) _GLIBCXX_USE_NOEXCEPT; #endif virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; /** Returns a C-style character string describing the general cause of * the current error (the same string passed to the ctor). */ virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; # ifdef _GLIBCXX_TM_TS_INTERNAL friend void* ::_txnal_runtime_error_get_msg(void* e); # endif }; /** Thrown to indicate range errors in internal computations. */ class range_error : public runtime_error { public: explicit range_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit range_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~range_error() _GLIBCXX_USE_NOEXCEPT; }; /** Thrown to indicate arithmetic overflow. */ class overflow_error : public runtime_error { public: explicit overflow_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit overflow_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~overflow_error() _GLIBCXX_USE_NOEXCEPT; }; /** Thrown to indicate arithmetic underflow. */ class underflow_error : public runtime_error { public: explicit underflow_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit underflow_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~underflow_error() _GLIBCXX_USE_NOEXCEPT; }; // @} group exceptions _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _GLIBCXX_STDEXCEPT */ 8/functional000064400000111566152526447520007026 0ustar00// -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * Copyright (c) 1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ /** @file include/functional * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_FUNCTIONAL #define _GLIBCXX_FUNCTIONAL 1 #pragma GCC system_header #include #include #if __cplusplus >= 201103L #include #include #include #include #include #include // std::reference_wrapper and _Mem_fn_traits #include // std::function #if __cplusplus > 201402L # include # include # include # include # include #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus > 201402L # define __cpp_lib_invoke 201411 /// Invoke a callable object. template inline invoke_result_t<_Callable, _Args...> invoke(_Callable&& __fn, _Args&&... __args) noexcept(is_nothrow_invocable_v<_Callable, _Args...>) { return std::__invoke(std::forward<_Callable>(__fn), std::forward<_Args>(__args)...); } #endif template::value> class _Mem_fn_base : public _Mem_fn_traits<_MemFunPtr>::__maybe_type { using _Traits = _Mem_fn_traits<_MemFunPtr>; using _Arity = typename _Traits::__arity; using _Varargs = typename _Traits::__vararg; template friend struct _Bind_check_arity; _MemFunPtr _M_pmf; public: using result_type = typename _Traits::__result_type; explicit constexpr _Mem_fn_base(_MemFunPtr __pmf) noexcept : _M_pmf(__pmf) { } template auto operator()(_Args&&... __args) const noexcept(noexcept( std::__invoke(_M_pmf, std::forward<_Args>(__args)...))) -> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...)) { return std::__invoke(_M_pmf, std::forward<_Args>(__args)...); } }; // Partial specialization for member object pointers. template class _Mem_fn_base<_MemObjPtr, false> { using _Arity = integral_constant; using _Varargs = false_type; template friend struct _Bind_check_arity; _MemObjPtr _M_pm; public: explicit constexpr _Mem_fn_base(_MemObjPtr __pm) noexcept : _M_pm(__pm) { } template auto operator()(_Tp&& __obj) const noexcept(noexcept(std::__invoke(_M_pm, std::forward<_Tp>(__obj)))) -> decltype(std::__invoke(_M_pm, std::forward<_Tp>(__obj))) { return std::__invoke(_M_pm, std::forward<_Tp>(__obj)); } }; template struct _Mem_fn; // undefined template struct _Mem_fn<_Res _Class::*> : _Mem_fn_base<_Res _Class::*> { using _Mem_fn_base<_Res _Class::*>::_Mem_fn_base; }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2048. Unnecessary mem_fn overloads /** * @brief Returns a function object that forwards to the member * pointer @a pm. * @ingroup functors */ template inline _Mem_fn<_Tp _Class::*> mem_fn(_Tp _Class::* __pm) noexcept { return _Mem_fn<_Tp _Class::*>(__pm); } /** * @brief Determines if the given type _Tp is a function object that * should be treated as a subexpression when evaluating calls to * function objects returned by bind(). * * C++11 [func.bind.isbind]. * @ingroup binders */ template struct is_bind_expression : public false_type { }; /** * @brief Determines if the given type _Tp is a placeholder in a * bind() expression and, if so, which placeholder it is. * * C++11 [func.bind.isplace]. * @ingroup binders */ template struct is_placeholder : public integral_constant { }; #if __cplusplus > 201402L template inline constexpr bool is_bind_expression_v = is_bind_expression<_Tp>::value; template inline constexpr int is_placeholder_v = is_placeholder<_Tp>::value; #endif // C++17 /** @brief The type of placeholder objects defined by libstdc++. * @ingroup binders */ template struct _Placeholder { }; /** @namespace std::placeholders * @brief ISO C++11 entities sub-namespace for functional. * @ingroup binders */ namespace placeholders { /* Define a large number of placeholders. There is no way to * simplify this with variadic templates, because we're introducing * unique names for each. */ extern const _Placeholder<1> _1; extern const _Placeholder<2> _2; extern const _Placeholder<3> _3; extern const _Placeholder<4> _4; extern const _Placeholder<5> _5; extern const _Placeholder<6> _6; extern const _Placeholder<7> _7; extern const _Placeholder<8> _8; extern const _Placeholder<9> _9; extern const _Placeholder<10> _10; extern const _Placeholder<11> _11; extern const _Placeholder<12> _12; extern const _Placeholder<13> _13; extern const _Placeholder<14> _14; extern const _Placeholder<15> _15; extern const _Placeholder<16> _16; extern const _Placeholder<17> _17; extern const _Placeholder<18> _18; extern const _Placeholder<19> _19; extern const _Placeholder<20> _20; extern const _Placeholder<21> _21; extern const _Placeholder<22> _22; extern const _Placeholder<23> _23; extern const _Placeholder<24> _24; extern const _Placeholder<25> _25; extern const _Placeholder<26> _26; extern const _Placeholder<27> _27; extern const _Placeholder<28> _28; extern const _Placeholder<29> _29; } /** * Partial specialization of is_placeholder that provides the placeholder * number for the placeholder objects defined by libstdc++. * @ingroup binders */ template struct is_placeholder<_Placeholder<_Num> > : public integral_constant { }; template struct is_placeholder > : public integral_constant { }; // Like tuple_element_t but SFINAE-friendly. template using _Safe_tuple_element_t = typename enable_if<(__i < tuple_size<_Tuple>::value), tuple_element<__i, _Tuple>>::type::type; /** * Maps an argument to bind() into an actual argument to the bound * function object [func.bind.bind]/10. Only the first parameter should * be specified: the rest are used to determine among the various * implementations. Note that, although this class is a function * object, it isn't entirely normal because it takes only two * parameters regardless of the number of parameters passed to the * bind expression. The first parameter is the bound argument and * the second parameter is a tuple containing references to the * rest of the arguments. */ template::value, bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)> class _Mu; /** * If the argument is reference_wrapper<_Tp>, returns the * underlying reference. * C++11 [func.bind.bind] p10 bullet 1. */ template class _Mu, false, false> { public: /* Note: This won't actually work for const volatile * reference_wrappers, because reference_wrapper::get() is const * but not volatile-qualified. This might be a defect in the TR. */ template _Tp& operator()(_CVRef& __arg, _Tuple&) const volatile { return __arg.get(); } }; /** * If the argument is a bind expression, we invoke the underlying * function object with the same cv-qualifiers as we are given and * pass along all of our arguments (unwrapped). * C++11 [func.bind.bind] p10 bullet 2. */ template class _Mu<_Arg, true, false> { public: template auto operator()(_CVArg& __arg, tuple<_Args...>& __tuple) const volatile -> decltype(__arg(declval<_Args>()...)) { // Construct an index tuple and forward to __call typedef typename _Build_index_tuple::__type _Indexes; return this->__call(__arg, __tuple, _Indexes()); } private: // Invokes the underlying function object __arg by unpacking all // of the arguments in the tuple. template auto __call(_CVArg& __arg, tuple<_Args...>& __tuple, const _Index_tuple<_Indexes...>&) const volatile -> decltype(__arg(declval<_Args>()...)) { return __arg(std::get<_Indexes>(std::move(__tuple))...); } }; /** * If the argument is a placeholder for the Nth argument, returns * a reference to the Nth argument to the bind function object. * C++11 [func.bind.bind] p10 bullet 3. */ template class _Mu<_Arg, false, true> { public: template _Safe_tuple_element_t<(is_placeholder<_Arg>::value - 1), _Tuple>&& operator()(const volatile _Arg&, _Tuple& __tuple) const volatile { return ::std::get<(is_placeholder<_Arg>::value - 1)>(std::move(__tuple)); } }; /** * If the argument is just a value, returns a reference to that * value. The cv-qualifiers on the reference are determined by the caller. * C++11 [func.bind.bind] p10 bullet 4. */ template class _Mu<_Arg, false, false> { public: template _CVArg&& operator()(_CVArg&& __arg, _Tuple&) const volatile { return std::forward<_CVArg>(__arg); } }; // std::get for volatile-qualified tuples template inline auto __volget(volatile tuple<_Tp...>& __tuple) -> __tuple_element_t<_Ind, tuple<_Tp...>> volatile& { return std::get<_Ind>(const_cast&>(__tuple)); } // std::get for const-volatile-qualified tuples template inline auto __volget(const volatile tuple<_Tp...>& __tuple) -> __tuple_element_t<_Ind, tuple<_Tp...>> const volatile& { return std::get<_Ind>(const_cast&>(__tuple)); } /// Type of the function object returned from bind(). template struct _Bind; template class _Bind<_Functor(_Bound_args...)> : public _Weak_result_type<_Functor> { typedef typename _Build_index_tuple::__type _Bound_indexes; _Functor _M_f; tuple<_Bound_args...> _M_bound_args; // Call unqualified template _Result __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) { return std::__invoke(_M_f, _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)... ); } // Call as const template _Result __call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const { return std::__invoke(_M_f, _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)... ); } // Call as volatile template _Result __call_v(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile { return std::__invoke(_M_f, _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)... ); } // Call as const volatile template _Result __call_c_v(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const volatile { return std::__invoke(_M_f, _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)... ); } template using _Mu_type = decltype( _Mu::type>()( std::declval<_BoundArg&>(), std::declval<_CallArgs&>()) ); template using _Res_type_impl = typename result_of< _Fn&(_Mu_type<_BArgs, _CallArgs>&&...) >::type; template using _Res_type = _Res_type_impl<_Functor, _CallArgs, _Bound_args...>; template using __dependent = typename enable_if::value+1), _Functor>::type; template class __cv_quals> using _Res_type_cv = _Res_type_impl< typename __cv_quals<__dependent<_CallArgs>>::type, _CallArgs, typename __cv_quals<_Bound_args>::type...>; public: template explicit _Bind(const _Functor& __f, _Args&&... __args) : _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...) { } template explicit _Bind(_Functor&& __f, _Args&&... __args) : _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...) { } _Bind(const _Bind&) = default; _Bind(_Bind&& __b) : _M_f(std::move(__b._M_f)), _M_bound_args(std::move(__b._M_bound_args)) { } // Call unqualified template>> _Result operator()(_Args&&... __args) { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as const template, add_const>> _Result operator()(_Args&&... __args) const { return this->__call_c<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } #if __cplusplus > 201402L # define _GLIBCXX_DEPR_BIND \ [[deprecated("std::bind does not support volatile in C++17")]] #else # define _GLIBCXX_DEPR_BIND #endif // Call as volatile template, add_volatile>> _GLIBCXX_DEPR_BIND _Result operator()(_Args&&... __args) volatile { return this->__call_v<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as const volatile template, add_cv>> _GLIBCXX_DEPR_BIND _Result operator()(_Args&&... __args) const volatile { return this->__call_c_v<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } }; /// Type of the function object returned from bind(). template struct _Bind_result; template class _Bind_result<_Result, _Functor(_Bound_args...)> { typedef typename _Build_index_tuple::__type _Bound_indexes; _Functor _M_f; tuple<_Bound_args...> _M_bound_args; // sfinae types template using __enable_if_void = typename enable_if{}>::type; template using __disable_if_void = typename enable_if{}, _Result>::type; // Call unqualified template __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) { return std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } // Call unqualified, return void template __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) { std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } // Call as const template __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const { return std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } // Call as const, return void template __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const { std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } // Call as volatile template __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile { return std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } // Call as volatile, return void template __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile { std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } // Call as const volatile template __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const volatile { return std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } // Call as const volatile, return void template __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const volatile { std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } public: typedef _Result result_type; template explicit _Bind_result(const _Functor& __f, _Args&&... __args) : _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...) { } template explicit _Bind_result(_Functor&& __f, _Args&&... __args) : _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...) { } _Bind_result(const _Bind_result&) = default; _Bind_result(_Bind_result&& __b) : _M_f(std::move(__b._M_f)), _M_bound_args(std::move(__b._M_bound_args)) { } // Call unqualified template result_type operator()(_Args&&... __args) { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as const template result_type operator()(_Args&&... __args) const { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as volatile template _GLIBCXX_DEPR_BIND result_type operator()(_Args&&... __args) volatile { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as const volatile template _GLIBCXX_DEPR_BIND result_type operator()(_Args&&... __args) const volatile { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } }; #undef _GLIBCXX_DEPR_BIND /** * @brief Class template _Bind is always a bind expression. * @ingroup binders */ template struct is_bind_expression<_Bind<_Signature> > : public true_type { }; /** * @brief Class template _Bind is always a bind expression. * @ingroup binders */ template struct is_bind_expression > : public true_type { }; /** * @brief Class template _Bind is always a bind expression. * @ingroup binders */ template struct is_bind_expression > : public true_type { }; /** * @brief Class template _Bind is always a bind expression. * @ingroup binders */ template struct is_bind_expression> : public true_type { }; /** * @brief Class template _Bind_result is always a bind expression. * @ingroup binders */ template struct is_bind_expression<_Bind_result<_Result, _Signature>> : public true_type { }; /** * @brief Class template _Bind_result is always a bind expression. * @ingroup binders */ template struct is_bind_expression> : public true_type { }; /** * @brief Class template _Bind_result is always a bind expression. * @ingroup binders */ template struct is_bind_expression> : public true_type { }; /** * @brief Class template _Bind_result is always a bind expression. * @ingroup binders */ template struct is_bind_expression> : public true_type { }; template struct _Bind_check_arity { }; template struct _Bind_check_arity<_Ret (*)(_Args...), _BoundArgs...> { static_assert(sizeof...(_BoundArgs) == sizeof...(_Args), "Wrong number of arguments for function"); }; template struct _Bind_check_arity<_Ret (*)(_Args......), _BoundArgs...> { static_assert(sizeof...(_BoundArgs) >= sizeof...(_Args), "Wrong number of arguments for function"); }; template struct _Bind_check_arity<_Tp _Class::*, _BoundArgs...> { using _Arity = typename _Mem_fn<_Tp _Class::*>::_Arity; using _Varargs = typename _Mem_fn<_Tp _Class::*>::_Varargs; static_assert(_Varargs::value ? sizeof...(_BoundArgs) >= _Arity::value + 1 : sizeof...(_BoundArgs) == _Arity::value + 1, "Wrong number of arguments for pointer-to-member"); }; // Trait type used to remove std::bind() from overload set via SFINAE // when first argument has integer type, so that std::bind() will // not be a better match than ::bind() from the BSD Sockets API. template::type> using __is_socketlike = __or_, is_enum<_Tp2>>; template struct _Bind_helper : _Bind_check_arity::type, _BoundArgs...> { typedef typename decay<_Func>::type __func_type; typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type; }; // Partial specialization for is_socketlike == true, does not define // nested type so std::bind() will not participate in overload resolution // when the first argument might be a socket file descriptor. template struct _Bind_helper { }; /** * @brief Function template for std::bind. * @ingroup binders */ template inline typename _Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type bind(_Func&& __f, _BoundArgs&&... __args) { typedef _Bind_helper __helper_type; return typename __helper_type::type(std::forward<_Func>(__f), std::forward<_BoundArgs>(__args)...); } template struct _Bindres_helper : _Bind_check_arity::type, _BoundArgs...> { typedef typename decay<_Func>::type __functor_type; typedef _Bind_result<_Result, __functor_type(typename decay<_BoundArgs>::type...)> type; }; /** * @brief Function template for std::bind. * @ingroup binders */ template inline typename _Bindres_helper<_Result, _Func, _BoundArgs...>::type bind(_Func&& __f, _BoundArgs&&... __args) { typedef _Bindres_helper<_Result, _Func, _BoundArgs...> __helper_type; return typename __helper_type::type(std::forward<_Func>(__f), std::forward<_BoundArgs>(__args)...); } #if __cplusplus >= 201402L /// Generalized negator. template class _Not_fn { template using __inv_res_t = typename __invoke_result<_Fn2, _Args...>::type; template static decltype(!std::declval<_Tp>()) _S_not() noexcept(noexcept(!std::declval<_Tp>())); public: template _Not_fn(_Fn2&& __fn, int) : _M_fn(std::forward<_Fn2>(__fn)) { } _Not_fn(const _Not_fn& __fn) = default; _Not_fn(_Not_fn&& __fn) = default; ~_Not_fn() = default; // Macro to define operator() with given cv-qualifiers ref-qualifiers, // forwarding _M_fn and the function arguments with the same qualifiers, // and deducing the return type and exception-specification. #define _GLIBCXX_NOT_FN_CALL_OP( _QUALS ) \ template \ decltype(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>()) \ operator()(_Args&&... __args) _QUALS \ noexcept(__is_nothrow_invocable<_Fn _QUALS, _Args...>::value \ && noexcept(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())) \ { \ return !std::__invoke(std::forward< _Fn _QUALS >(_M_fn), \ std::forward<_Args>(__args)...); \ } _GLIBCXX_NOT_FN_CALL_OP( & ) _GLIBCXX_NOT_FN_CALL_OP( const & ) _GLIBCXX_NOT_FN_CALL_OP( && ) _GLIBCXX_NOT_FN_CALL_OP( const && ) #undef _GLIBCXX_NOT_FN_CALL private: _Fn _M_fn; }; template struct __is_byte_like : false_type { }; template struct __is_byte_like<_Tp, equal_to<_Tp>> : __bool_constant::value> { }; template struct __is_byte_like<_Tp, equal_to> : __bool_constant::value> { }; #if __cplusplus >= 201703L // Declare std::byte (full definition is in ). enum class byte : unsigned char; template<> struct __is_byte_like> : true_type { }; template<> struct __is_byte_like> : true_type { }; #define __cpp_lib_not_fn 201603 /// [func.not_fn] Function template not_fn template inline auto not_fn(_Fn&& __fn) noexcept(std::is_nothrow_constructible, _Fn&&>::value) { return _Not_fn>{std::forward<_Fn>(__fn), 0}; } // Searchers #define __cpp_lib_boyer_moore_searcher 201603 template> class default_searcher { public: default_searcher(_ForwardIterator1 __pat_first, _ForwardIterator1 __pat_last, _BinaryPredicate __pred = _BinaryPredicate()) : _M_m(__pat_first, __pat_last, std::move(__pred)) { } template pair<_ForwardIterator2, _ForwardIterator2> operator()(_ForwardIterator2 __first, _ForwardIterator2 __last) const { _ForwardIterator2 __first_ret = std::search(__first, __last, std::get<0>(_M_m), std::get<1>(_M_m), std::get<2>(_M_m)); auto __ret = std::make_pair(__first_ret, __first_ret); if (__ret.first != __last) std::advance(__ret.second, std::distance(std::get<0>(_M_m), std::get<1>(_M_m))); return __ret; } private: tuple<_ForwardIterator1, _ForwardIterator1, _BinaryPredicate> _M_m; }; template struct __boyer_moore_map_base { template __boyer_moore_map_base(_RAIter __pat, size_t __patlen, _Hash&& __hf, _Pred&& __pred) : _M_bad_char{ __patlen, std::move(__hf), std::move(__pred) } { if (__patlen > 0) for (__diff_type __i = 0; __i < __patlen - 1; ++__i) _M_bad_char[__pat[__i]] = __patlen - 1 - __i; } using __diff_type = _Tp; __diff_type _M_lookup(_Key __key, __diff_type __not_found) const { auto __iter = _M_bad_char.find(__key); if (__iter == _M_bad_char.end()) return __not_found; return __iter->second; } _Pred _M_pred() const { return _M_bad_char.key_eq(); } _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred> _M_bad_char; }; template struct __boyer_moore_array_base { template __boyer_moore_array_base(_RAIter __pat, size_t __patlen, _Unused&&, _Pred&& __pred) : _M_bad_char{ _GLIBCXX_STD_C::array<_Tp, _Len>{}, std::move(__pred) } { std::get<0>(_M_bad_char).fill(__patlen); if (__patlen > 0) for (__diff_type __i = 0; __i < __patlen - 1; ++__i) { auto __ch = __pat[__i]; using _UCh = make_unsigned_t; auto __uch = static_cast<_UCh>(__ch); std::get<0>(_M_bad_char)[__uch] = __patlen - 1 - __i; } } using __diff_type = _Tp; template __diff_type _M_lookup(_Key __key, __diff_type __not_found) const { auto __ukey = static_cast>(__key); if (__ukey >= _Len) return __not_found; return std::get<0>(_M_bad_char)[__ukey]; } const _Pred& _M_pred() const { return std::get<1>(_M_bad_char); } tuple<_GLIBCXX_STD_C::array<_Tp, _Len>, _Pred> _M_bad_char; }; // Use __boyer_moore_array_base when pattern consists of narrow characters // (or std::byte) and uses std::equal_to as the predicate. template::value_type, typename _Diff = typename iterator_traits<_RAIter>::difference_type> using __boyer_moore_base_t = conditional_t<__is_byte_like<_Val, _Pred>::value, __boyer_moore_array_base<_Diff, 256, _Pred>, __boyer_moore_map_base<_Val, _Diff, _Hash, _Pred>>; template::value_type>, typename _BinaryPredicate = equal_to<>> class boyer_moore_searcher : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate> { using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>; using typename _Base::__diff_type; public: boyer_moore_searcher(_RAIter __pat_first, _RAIter __pat_last, _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()); template pair<_RandomAccessIterator2, _RandomAccessIterator2> operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const; private: bool _M_is_prefix(_RAIter __word, __diff_type __len, __diff_type __pos) { const auto& __pred = this->_M_pred(); __diff_type __suffixlen = __len - __pos; for (__diff_type __i = 0; __i < __suffixlen; ++__i) if (!__pred(__word[__i], __word[__pos + __i])) return false; return true; } __diff_type _M_suffix_length(_RAIter __word, __diff_type __len, __diff_type __pos) { const auto& __pred = this->_M_pred(); __diff_type __i = 0; while (__pred(__word[__pos - __i], __word[__len - 1 - __i]) && __i < __pos) { ++__i; } return __i; } template __diff_type _M_bad_char_shift(_Tp __c) const { return this->_M_lookup(__c, _M_pat_end - _M_pat); } _RAIter _M_pat; _RAIter _M_pat_end; _GLIBCXX_STD_C::vector<__diff_type> _M_good_suffix; }; template::value_type>, typename _BinaryPredicate = equal_to<>> class boyer_moore_horspool_searcher : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate> { using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>; using typename _Base::__diff_type; public: boyer_moore_horspool_searcher(_RAIter __pat, _RAIter __pat_end, _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)), _M_pat(__pat), _M_pat_end(__pat_end) { } template pair<_RandomAccessIterator2, _RandomAccessIterator2> operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const { const auto& __pred = this->_M_pred(); auto __patlen = _M_pat_end - _M_pat; if (__patlen == 0) return std::make_pair(__first, __first); auto __len = __last - __first; while (__len >= __patlen) { for (auto __scan = __patlen - 1; __pred(__first[__scan], _M_pat[__scan]); --__scan) if (__scan == 0) return std::make_pair(__first, __first + __patlen); auto __shift = _M_bad_char_shift(__first[__patlen - 1]); __len -= __shift; __first += __shift; } return std::make_pair(__last, __last); } private: template __diff_type _M_bad_char_shift(_Tp __c) const { return this->_M_lookup(__c, _M_pat_end - _M_pat); } _RAIter _M_pat; _RAIter _M_pat_end; }; template boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>:: boyer_moore_searcher(_RAIter __pat, _RAIter __pat_end, _Hash __hf, _BinaryPredicate __pred) : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)), _M_pat(__pat), _M_pat_end(__pat_end), _M_good_suffix(__pat_end - __pat) { auto __patlen = __pat_end - __pat; if (__patlen == 0) return; __diff_type __last_prefix = __patlen - 1; for (__diff_type __p = __patlen - 1; __p >= 0; --__p) { if (_M_is_prefix(__pat, __patlen, __p + 1)) __last_prefix = __p + 1; _M_good_suffix[__p] = __last_prefix + (__patlen - 1 - __p); } for (__diff_type __p = 0; __p < __patlen - 1; ++__p) { auto __slen = _M_suffix_length(__pat, __patlen, __p); auto __pos = __patlen - 1 - __slen; if (!__pred(__pat[__p - __slen], __pat[__pos])) _M_good_suffix[__pos] = __patlen - 1 - __p + __slen; } } template template pair<_RandomAccessIterator2, _RandomAccessIterator2> boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>:: operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const { auto __patlen = _M_pat_end - _M_pat; if (__patlen == 0) return std::make_pair(__first, __first); const auto& __pred = this->_M_pred(); __diff_type __i = __patlen - 1; auto __stringlen = __last - __first; while (__i < __stringlen) { __diff_type __j = __patlen - 1; while (__j >= 0 && __pred(__first[__i], _M_pat[__j])) { --__i; --__j; } if (__j < 0) { const auto __match = __first + __i + 1; return std::make_pair(__match, __match + __patlen); } __i += std::max(_M_bad_char_shift(__first[__i]), _M_good_suffix[__j]); } return std::make_pair(__last, __last); } #endif // C++17 #endif // C++14 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_FUNCTIONAL 8/cstdarg000064400000003514152526447520006304 0ustar00// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/cstdarg * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c stdarg.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 20.4.6 C library // #pragma GCC system_header #undef __need___va_list #include #include #ifndef _GLIBCXX_CSTDARG #define _GLIBCXX_CSTDARG 1 // Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 #ifndef va_end #define va_end(ap) va_end (ap) #endif namespace std { using ::va_list; } // namespace std #endif 8/condition_variable000064400000021372152526447520010512 0ustar00// -*- C++ -*- // Copyright (C) 2008-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/condition_variable * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_CONDITION_VARIABLE #define _GLIBCXX_CONDITION_VARIABLE 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #include #include #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup condition_variables Condition Variables * @ingroup concurrency * * Classes for condition_variable support. * @{ */ /// cv_status enum class cv_status { no_timeout, timeout }; /// condition_variable class condition_variable { typedef chrono::system_clock __clock_t; typedef __gthread_cond_t __native_type; #ifdef __GTHREAD_COND_INIT __native_type _M_cond = __GTHREAD_COND_INIT; #else __native_type _M_cond; #endif public: typedef __native_type* native_handle_type; condition_variable() noexcept; ~condition_variable() noexcept; condition_variable(const condition_variable&) = delete; condition_variable& operator=(const condition_variable&) = delete; void notify_one() noexcept; void notify_all() noexcept; void wait(unique_lock& __lock) noexcept; template void wait(unique_lock& __lock, _Predicate __p) { while (!__p()) wait(__lock); } template cv_status wait_until(unique_lock& __lock, const chrono::time_point<__clock_t, _Duration>& __atime) { return __wait_until_impl(__lock, __atime); } template cv_status wait_until(unique_lock& __lock, const chrono::time_point<_Clock, _Duration>& __atime) { // DR 887 - Sync unknown clock to known clock. const typename _Clock::time_point __c_entry = _Clock::now(); const __clock_t::time_point __s_entry = __clock_t::now(); const auto __delta = __atime - __c_entry; const auto __s_atime = __s_entry + __delta; return __wait_until_impl(__lock, __s_atime); } template bool wait_until(unique_lock& __lock, const chrono::time_point<_Clock, _Duration>& __atime, _Predicate __p) { while (!__p()) if (wait_until(__lock, __atime) == cv_status::timeout) return __p(); return true; } template cv_status wait_for(unique_lock& __lock, const chrono::duration<_Rep, _Period>& __rtime) { using __dur = typename __clock_t::duration; auto __reltime = chrono::duration_cast<__dur>(__rtime); if (__reltime < __rtime) ++__reltime; return wait_until(__lock, __clock_t::now() + __reltime); } template bool wait_for(unique_lock& __lock, const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p) { using __dur = typename __clock_t::duration; auto __reltime = chrono::duration_cast<__dur>(__rtime); if (__reltime < __rtime) ++__reltime; return wait_until(__lock, __clock_t::now() + __reltime, std::move(__p)); } native_handle_type native_handle() { return &_M_cond; } private: template cv_status __wait_until_impl(unique_lock& __lock, const chrono::time_point<__clock_t, _Dur>& __atime) { auto __s = chrono::time_point_cast(__atime); auto __ns = chrono::duration_cast(__atime - __s); __gthread_time_t __ts = { static_cast(__s.time_since_epoch().count()), static_cast(__ns.count()) }; __gthread_cond_timedwait(&_M_cond, __lock.mutex()->native_handle(), &__ts); return (__clock_t::now() < __atime ? cv_status::no_timeout : cv_status::timeout); } }; void notify_all_at_thread_exit(condition_variable&, unique_lock); struct __at_thread_exit_elt { __at_thread_exit_elt* _M_next; void (*_M_cb)(void*); }; inline namespace _V2 { /// condition_variable_any // Like above, but mutex is not required to have try_lock. class condition_variable_any { typedef chrono::system_clock __clock_t; condition_variable _M_cond; shared_ptr _M_mutex; // scoped unlock - unlocks in ctor, re-locks in dtor template struct _Unlock { explicit _Unlock(_Lock& __lk) : _M_lock(__lk) { __lk.unlock(); } ~_Unlock() noexcept(false) { if (uncaught_exception()) { __try { _M_lock.lock(); } __catch(const __cxxabiv1::__forced_unwind&) { __throw_exception_again; } __catch(...) { } } else _M_lock.lock(); } _Unlock(const _Unlock&) = delete; _Unlock& operator=(const _Unlock&) = delete; _Lock& _M_lock; }; public: condition_variable_any() : _M_mutex(std::make_shared()) { } ~condition_variable_any() = default; condition_variable_any(const condition_variable_any&) = delete; condition_variable_any& operator=(const condition_variable_any&) = delete; void notify_one() noexcept { lock_guard __lock(*_M_mutex); _M_cond.notify_one(); } void notify_all() noexcept { lock_guard __lock(*_M_mutex); _M_cond.notify_all(); } template void wait(_Lock& __lock) { shared_ptr __mutex = _M_mutex; unique_lock __my_lock(*__mutex); _Unlock<_Lock> __unlock(__lock); // *__mutex must be unlocked before re-locking __lock so move // ownership of *__mutex lock to an object with shorter lifetime. unique_lock __my_lock2(std::move(__my_lock)); _M_cond.wait(__my_lock2); } template void wait(_Lock& __lock, _Predicate __p) { while (!__p()) wait(__lock); } template cv_status wait_until(_Lock& __lock, const chrono::time_point<_Clock, _Duration>& __atime) { shared_ptr __mutex = _M_mutex; unique_lock __my_lock(*__mutex); _Unlock<_Lock> __unlock(__lock); // *__mutex must be unlocked before re-locking __lock so move // ownership of *__mutex lock to an object with shorter lifetime. unique_lock __my_lock2(std::move(__my_lock)); return _M_cond.wait_until(__my_lock2, __atime); } template bool wait_until(_Lock& __lock, const chrono::time_point<_Clock, _Duration>& __atime, _Predicate __p) { while (!__p()) if (wait_until(__lock, __atime) == cv_status::timeout) return __p(); return true; } template cv_status wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime) { return wait_until(__lock, __clock_t::now() + __rtime); } template bool wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p) { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); } }; } // end inline namespace // @} group condition_variables _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif // _GLIBCXX_CONDITION_VARIABLE 8/variant000064400000136162152526447520006327 0ustar00// -*- C++ -*- // Copyright (C) 2016-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file variant * This is the C++ Library header. */ #ifndef _GLIBCXX_VARIANT #define _GLIBCXX_VARIANT 1 #pragma GCC system_header #if __cplusplus >= 201703L #include #include #include #include #include #include #include #include #include #include #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { namespace __variant { template struct _Nth_type; template struct _Nth_type<_Np, _First, _Rest...> : _Nth_type<_Np-1, _Rest...> { }; template struct _Nth_type<0, _First, _Rest...> { using type = _First; }; } // namespace __variant } // namespace __detail #define __cpp_lib_variant 201606L template class tuple; template class variant; template struct hash; template struct variant_size; template struct variant_size : variant_size<_Variant> {}; template struct variant_size : variant_size<_Variant> {}; template struct variant_size : variant_size<_Variant> {}; template struct variant_size> : std::integral_constant {}; template inline constexpr size_t variant_size_v = variant_size<_Variant>::value; template struct variant_alternative; template struct variant_alternative<_Np, variant<_First, _Rest...>> : variant_alternative<_Np-1, variant<_Rest...>> {}; template struct variant_alternative<0, variant<_First, _Rest...>> { using type = _First; }; template using variant_alternative_t = typename variant_alternative<_Np, _Variant>::type; template struct variant_alternative<_Np, const _Variant> { using type = add_const_t>; }; template struct variant_alternative<_Np, volatile _Variant> { using type = add_volatile_t>; }; template struct variant_alternative<_Np, const volatile _Variant> { using type = add_cv_t>; }; inline constexpr size_t variant_npos = -1; template constexpr variant_alternative_t<_Np, variant<_Types...>>& get(variant<_Types...>&); template constexpr variant_alternative_t<_Np, variant<_Types...>>&& get(variant<_Types...>&&); template constexpr variant_alternative_t<_Np, variant<_Types...>> const& get(const variant<_Types...>&); template constexpr variant_alternative_t<_Np, variant<_Types...>> const&& get(const variant<_Types...>&&); namespace __detail { namespace __variant { // Returns the first apparence of _Tp in _Types. // Returns sizeof...(_Types) if _Tp is not in _Types. template struct __index_of : std::integral_constant {}; template inline constexpr size_t __index_of_v = __index_of<_Tp, _Types...>::value; template struct __index_of<_Tp, _First, _Rest...> : std::integral_constant ? 0 : __index_of_v<_Tp, _Rest...> + 1> {}; // _Uninitialized is guaranteed to be a literal type, even if T is not. // We have to do this, because [basic.types]p10.5.3 (n4606) is not implemented // yet. When it's implemented, _Uninitialized can be changed to the alias // to T, therefore equivalent to being removed entirely. // // Another reason we may not want to remove _Uninitialzied may be that, we // want _Uninitialized to be trivially destructible, no matter whether T // is; but we will see. template> struct _Uninitialized; template struct _Uninitialized<_Type, true> { template constexpr _Uninitialized(in_place_index_t<0>, _Args&&... __args) : _M_storage(std::forward<_Args>(__args)...) { } constexpr const _Type& _M_get() const & { return _M_storage; } constexpr _Type& _M_get() & { return _M_storage; } constexpr const _Type&& _M_get() const && { return std::move(_M_storage); } constexpr _Type&& _M_get() && { return std::move(_M_storage); } _Type _M_storage; }; template struct _Uninitialized<_Type, false> { template constexpr _Uninitialized(in_place_index_t<0>, _Args&&... __args) { ::new (&_M_storage) _Type(std::forward<_Args>(__args)...); } const _Type& _M_get() const & { return *_M_storage._M_ptr(); } _Type& _M_get() & { return *_M_storage._M_ptr(); } const _Type&& _M_get() const && { return std::move(*_M_storage._M_ptr()); } _Type&& _M_get() && { return std::move(*_M_storage._M_ptr()); } __gnu_cxx::__aligned_membuf<_Type> _M_storage; }; template _Ref __ref_cast(void* __ptr) { return static_cast<_Ref>(*static_cast*>(__ptr)); } template constexpr decltype(auto) __get(in_place_index_t<0>, _Union&& __u) { return std::forward<_Union>(__u)._M_first._M_get(); } template constexpr decltype(auto) __get(in_place_index_t<_Np>, _Union&& __u) { return __variant::__get(in_place_index<_Np-1>, std::forward<_Union>(__u)._M_rest); } // Returns the typed storage for __v. template constexpr decltype(auto) __get(_Variant&& __v) { return __variant::__get(std::in_place_index<_Np>, std::forward<_Variant>(__v)._M_u); } // Various functions as "vtable" entries, where those vtables are used by // polymorphic operations. template void __erased_ctor(void* __lhs, void* __rhs) { using _Type = remove_reference_t<_Lhs>; ::new (__lhs) _Type(__variant::__ref_cast<_Rhs>(__rhs)); } template void __erased_dtor(_Variant&& __v) { std::_Destroy(std::__addressof(__variant::__get<_Np>(__v))); } template void __erased_assign(void* __lhs, void* __rhs) { __variant::__ref_cast<_Lhs>(__lhs) = __variant::__ref_cast<_Rhs>(__rhs); } template void __erased_swap(void* __lhs, void* __rhs) { using std::swap; swap(__variant::__ref_cast<_Lhs>(__lhs), __variant::__ref_cast<_Rhs>(__rhs)); } #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \ template \ constexpr bool \ __erased_##__NAME(const _Variant& __lhs, const _Variant& __rhs) \ { \ return __variant::__get<_Np>(std::forward<_Variant>(__lhs)) \ __OP __variant::__get<_Np>(std::forward<_Variant>(__rhs)); \ } _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less) _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater) #undef _VARIANT_RELATION_FUNCTION_TEMPLATE template size_t __erased_hash(void* __t) { return std::hash>>{}( __variant::__ref_cast<_Tp>(__t)); } template struct _Traits { static constexpr bool _S_default_ctor = is_default_constructible_v::type>; static constexpr bool _S_copy_ctor = (is_copy_constructible_v<_Types> && ...); static constexpr bool _S_move_ctor = (is_move_constructible_v<_Types> && ...); static constexpr bool _S_copy_assign = _S_copy_ctor && _S_move_ctor && (is_copy_assignable_v<_Types> && ...); static constexpr bool _S_move_assign = _S_move_ctor && (is_move_assignable_v<_Types> && ...); static constexpr bool _S_trivial_dtor = (is_trivially_destructible_v<_Types> && ...); static constexpr bool _S_trivial_copy_ctor = (is_trivially_copy_constructible_v<_Types> && ...); static constexpr bool _S_trivial_move_ctor = (is_trivially_move_constructible_v<_Types> && ...); static constexpr bool _S_trivial_copy_assign = _S_trivial_dtor && (is_trivially_copy_assignable_v<_Types> && ...); static constexpr bool _S_trivial_move_assign = _S_trivial_dtor && (is_trivially_move_assignable_v<_Types> && ...); // The following nothrow traits are for non-trivial SMFs. Trivial SMFs // are always nothrow. static constexpr bool _S_nothrow_default_ctor = is_nothrow_default_constructible_v< typename _Nth_type<0, _Types...>::type>; static constexpr bool _S_nothrow_copy_ctor = false; static constexpr bool _S_nothrow_move_ctor = (is_nothrow_move_constructible_v<_Types> && ...); static constexpr bool _S_nothrow_copy_assign = false; static constexpr bool _S_nothrow_move_assign = _S_nothrow_move_ctor && (is_nothrow_move_assignable_v<_Types> && ...); }; // Defines members and ctors. template union _Variadic_union { }; template union _Variadic_union<_First, _Rest...> { constexpr _Variadic_union() : _M_rest() { } template constexpr _Variadic_union(in_place_index_t<0>, _Args&&... __args) : _M_first(in_place_index<0>, std::forward<_Args>(__args)...) { } template constexpr _Variadic_union(in_place_index_t<_Np>, _Args&&... __args) : _M_rest(in_place_index<_Np-1>, std::forward<_Args>(__args)...) { } _Uninitialized<_First> _M_first; _Variadic_union<_Rest...> _M_rest; }; // Defines index and the dtor, possibly trivial. template struct _Variant_storage; template using __select_index = typename __select_int::_Select_int_base::type::value_type; template struct _Variant_storage { template static constexpr void (*_S_vtable[])(const _Variant_storage&) = { &__erased_dtor... }; constexpr _Variant_storage() : _M_index(variant_npos) { } template constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args) : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...), _M_index(_Np) { } template constexpr void _M_reset_impl(std::index_sequence<__indices...>) { if (_M_index != __index_type(variant_npos)) _S_vtable<__indices...>[_M_index](*this); } void _M_reset() { _M_reset_impl(std::index_sequence_for<_Types...>{}); _M_index = variant_npos; } ~_Variant_storage() { _M_reset(); } void* _M_storage() const { return const_cast(static_cast( std::addressof(_M_u))); } constexpr bool _M_valid() const noexcept { return this->_M_index != __index_type(variant_npos); } _Variadic_union<_Types...> _M_u; using __index_type = __select_index<_Types...>; __index_type _M_index; }; template struct _Variant_storage { constexpr _Variant_storage() : _M_index(variant_npos) { } template constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args) : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...), _M_index(_Np) { } void _M_reset() { _M_index = variant_npos; } void* _M_storage() const { return const_cast(static_cast( std::addressof(_M_u))); } constexpr bool _M_valid() const noexcept { return this->_M_index != __index_type(variant_npos); } _Variadic_union<_Types...> _M_u; using __index_type = __select_index<_Types...>; __index_type _M_index; }; template using _Variant_storage_alias = _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>; // The following are (Copy|Move) (ctor|assign) layers for forwarding // triviality and handling non-trivial SMF behaviors. template struct _Copy_ctor_base : _Variant_storage_alias<_Types...> { using _Base = _Variant_storage_alias<_Types...>; using _Base::_Base; _Copy_ctor_base(const _Copy_ctor_base& __rhs) noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor) { if (__rhs._M_valid()) { static constexpr void (*_S_vtable[])(void*, void*) = { &__erased_ctor<_Types&, const _Types&>... }; _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage()); this->_M_index = __rhs._M_index; } } _Copy_ctor_base(_Copy_ctor_base&&) = default; _Copy_ctor_base& operator=(const _Copy_ctor_base&) = default; _Copy_ctor_base& operator=(_Copy_ctor_base&&) = default; }; template struct _Copy_ctor_base : _Variant_storage_alias<_Types...> { using _Base = _Variant_storage_alias<_Types...>; using _Base::_Base; }; template using _Copy_ctor_alias = _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>; template struct _Move_ctor_base : _Copy_ctor_alias<_Types...> { using _Base = _Copy_ctor_alias<_Types...>; using _Base::_Base; _Move_ctor_base(_Move_ctor_base&& __rhs) noexcept(_Traits<_Types...>::_S_nothrow_move_ctor) { if (__rhs._M_valid()) { static constexpr void (*_S_vtable[])(void*, void*) = { &__erased_ctor<_Types&, _Types&&>... }; _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage()); this->_M_index = __rhs._M_index; } } void _M_destructive_move(_Move_ctor_base&& __rhs) { this->~_Move_ctor_base(); __try { ::new (this) _Move_ctor_base(std::move(__rhs)); } __catch (...) { this->_M_index = variant_npos; __throw_exception_again; } } _Move_ctor_base(const _Move_ctor_base&) = default; _Move_ctor_base& operator=(const _Move_ctor_base&) = default; _Move_ctor_base& operator=(_Move_ctor_base&&) = default; }; template struct _Move_ctor_base : _Copy_ctor_alias<_Types...> { using _Base = _Copy_ctor_alias<_Types...>; using _Base::_Base; void _M_destructive_move(_Move_ctor_base&& __rhs) { this->~_Move_ctor_base(); ::new (this) _Move_ctor_base(std::move(__rhs)); } }; template using _Move_ctor_alias = _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>; template struct _Copy_assign_base : _Move_ctor_alias<_Types...> { using _Base = _Move_ctor_alias<_Types...>; using _Base::_Base; _Copy_assign_base& operator=(const _Copy_assign_base& __rhs) noexcept(_Traits<_Types...>::_S_nothrow_copy_assign) { if (this->_M_index == __rhs._M_index) { if (__rhs._M_valid()) { static constexpr void (*_S_vtable[])(void*, void*) = { &__erased_assign<_Types&, const _Types&>... }; _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage()); } } else { _Copy_assign_base __tmp(__rhs); this->_M_destructive_move(std::move(__tmp)); } __glibcxx_assert(this->_M_index == __rhs._M_index); return *this; } _Copy_assign_base(const _Copy_assign_base&) = default; _Copy_assign_base(_Copy_assign_base&&) = default; _Copy_assign_base& operator=(_Copy_assign_base&&) = default; }; template struct _Copy_assign_base : _Move_ctor_alias<_Types...> { using _Base = _Move_ctor_alias<_Types...>; using _Base::_Base; }; template using _Copy_assign_alias = _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>; template struct _Move_assign_base : _Copy_assign_alias<_Types...> { using _Base = _Copy_assign_alias<_Types...>; using _Base::_Base; _Move_assign_base& operator=(_Move_assign_base&& __rhs) noexcept(_Traits<_Types...>::_S_nothrow_move_assign) { if (this->_M_index == __rhs._M_index) { if (__rhs._M_valid()) { static constexpr void (*_S_vtable[])(void*, void*) = { &__erased_assign<_Types&, _Types&&>... }; _S_vtable[__rhs._M_index] (this->_M_storage(), __rhs._M_storage()); } } else { _Move_assign_base __tmp(std::move(__rhs)); this->_M_destructive_move(std::move(__tmp)); } __glibcxx_assert(this->_M_index == __rhs._M_index); return *this; } _Move_assign_base(const _Move_assign_base&) = default; _Move_assign_base(_Move_assign_base&&) = default; _Move_assign_base& operator=(const _Move_assign_base&) = default; }; template struct _Move_assign_base : _Copy_assign_alias<_Types...> { using _Base = _Copy_assign_alias<_Types...>; using _Base::_Base; }; template using _Move_assign_alias = _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>; template struct _Variant_base : _Move_assign_alias<_Types...> { using _Base = _Move_assign_alias<_Types...>; constexpr _Variant_base() noexcept(_Traits<_Types...>::_S_nothrow_default_ctor) : _Variant_base(in_place_index<0>) { } template constexpr explicit _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args) : _Base(__i, std::forward<_Args>(__args)...) { } _Variant_base(const _Variant_base&) = default; _Variant_base(_Variant_base&&) = default; _Variant_base& operator=(const _Variant_base&) = default; _Variant_base& operator=(_Variant_base&&) = default; }; // For how many times does _Tp appear in _Tuple? template struct __tuple_count; template inline constexpr size_t __tuple_count_v = __tuple_count<_Tp, _Tuple>::value; template struct __tuple_count<_Tp, tuple<_Types...>> : integral_constant { }; template struct __tuple_count<_Tp, tuple<_First, _Rest...>> : integral_constant< size_t, __tuple_count_v<_Tp, tuple<_Rest...>> + is_same_v<_Tp, _First>> { }; // TODO: Reuse this in ? template inline constexpr bool __exactly_once = __tuple_count_v<_Tp, tuple<_Types...>> == 1; // Takes _Types and create an overloaded _S_fun for each type. // If a type appears more than once in _Types, create only one overload. template struct __overload_set { static void _S_fun(); }; template struct __overload_set<_First, _Rest...> : __overload_set<_Rest...> { using __overload_set<_Rest...>::_S_fun; static integral_constant _S_fun(_First); }; template struct __overload_set : __overload_set<_Rest...> { using __overload_set<_Rest...>::_S_fun; }; // Helper for variant(_Tp&&) and variant::operator=(_Tp&&). // __accepted_index maps the arbitrary _Tp to an alternative type in _Variant. template struct __accepted_index { static constexpr size_t value = variant_npos; }; template struct __accepted_index< _Tp, variant<_Types...>, decltype(__overload_set<_Types...>::_S_fun(std::declval<_Tp>()), std::declval())> { static constexpr size_t value = sizeof...(_Types) - 1 - decltype(__overload_set<_Types...>:: _S_fun(std::declval<_Tp>()))::value; }; // Returns the raw storage for __v. template void* __get_storage(_Variant&& __v) { return __v._M_storage(); } // Used for storing multi-dimensional vtable. template struct _Multi_array { constexpr const _Tp& _M_access() const { return _M_data; } _Tp _M_data; }; template struct _Multi_array<_Tp, __first, __rest...> { template constexpr const _Tp& _M_access(size_t __first_index, _Args... __rest_indices) const { return _M_arr[__first_index]._M_access(__rest_indices...); } _Multi_array<_Tp, __rest...> _M_arr[__first]; }; // Creates a multi-dimensional vtable recursively. // // For example, // visit([](auto, auto){}, // variant(), // typedef'ed as V1 // variant()) // typedef'ed as V2 // will trigger instantiations of: // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<0>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<0, 0>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<0, 1>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<0, 2>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<1>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<1, 0>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<1, 1>> // __gen_vtable_impl<_Multi_array, // tuple, std::index_sequence<1, 2>> // The returned multi-dimensional vtable can be fast accessed by the visitor // using index calculation. template struct __gen_vtable_impl; template struct __gen_vtable_impl< _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>, tuple<_Variants...>, std::index_sequence<__indices...>> { using _Next = remove_reference_t::type>; using _Array_type = _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>; static constexpr _Array_type _S_apply() { _Array_type __vtable{}; _S_apply_all_alts( __vtable, make_index_sequence>()); return __vtable; } template static constexpr void _S_apply_all_alts(_Array_type& __vtable, std::index_sequence<__var_indices...>) { (_S_apply_single_alt<__var_indices>( __vtable._M_arr[__var_indices]), ...); } template static constexpr void _S_apply_single_alt(_Tp& __element) { using _Alternative = variant_alternative_t<__index, _Next>; __element = __gen_vtable_impl< remove_reference_t, tuple<_Variants...>, std::index_sequence<__indices..., __index>>::_S_apply(); } }; template struct __gen_vtable_impl< _Multi_array<_Result_type (*)(_Visitor, _Variants...)>, tuple<_Variants...>, std::index_sequence<__indices...>> { using _Array_type = _Multi_array<_Result_type (*)(_Visitor&&, _Variants...)>; static constexpr decltype(auto) __visit_invoke(_Visitor&& __visitor, _Variants... __vars) { return std::__invoke(std::forward<_Visitor>(__visitor), __variant::__get<__indices>(std::forward<_Variants>(__vars))...); } static constexpr auto _S_apply() { return _Array_type{&__visit_invoke}; } }; template struct __gen_vtable { using _Func_ptr = _Result_type (*)(_Visitor&&, _Variants...); using _Array_type = _Multi_array<_Func_ptr, variant_size_v>...>; static constexpr _Array_type _S_apply() { return __gen_vtable_impl<_Array_type, tuple<_Variants...>, std::index_sequence<>>::_S_apply(); } static constexpr auto _S_vtable = _S_apply(); }; template struct _Base_dedup : public _Tp { }; template struct _Variant_hash_base; template struct _Variant_hash_base, std::index_sequence<__indices...>> : _Base_dedup<__indices, __poison_hash>>... { }; } // namespace __variant } // namespace __detail template constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); return __v.index() == __detail::__variant::__index_of_v<_Tp, _Types...>; } template constexpr _Tp& get(variant<_Types...>& __v) { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v); } template constexpr _Tp&& get(variant<_Types...>&& __v) { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>( std::move(__v)); } template constexpr const _Tp& get(const variant<_Types...>& __v) { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v); } template constexpr const _Tp&& get(const variant<_Types...>&& __v) { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>( std::move(__v)); } template constexpr add_pointer_t>> get_if(variant<_Types...>* __ptr) noexcept { using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>; static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void"); if (__ptr && __ptr->index() == _Np) return &__detail::__variant::__get<_Np>(*__ptr); return nullptr; } template constexpr add_pointer_t>> get_if(const variant<_Types...>* __ptr) noexcept { using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>; static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void"); if (__ptr && __ptr->index() == _Np) return &__detail::__variant::__get<_Np>(*__ptr); return nullptr; } template constexpr add_pointer_t<_Tp> get_if(variant<_Types...>* __ptr) noexcept { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>( __ptr); } template constexpr add_pointer_t get_if(const variant<_Types...>* __ptr) noexcept { static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, "T should occur for exactly once in alternatives"); static_assert(!is_void_v<_Tp>, "_Tp should not be void"); return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>( __ptr); } struct monostate { }; #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \ template \ constexpr bool operator __OP(const variant<_Types...>& __lhs, \ const variant<_Types...>& __rhs) \ { \ return __lhs._M_##__NAME(__rhs, std::index_sequence_for<_Types...>{}); \ } \ \ constexpr bool operator __OP(monostate, monostate) noexcept \ { return 0 __OP 0; } _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less) _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater) #undef _VARIANT_RELATION_FUNCTION_TEMPLATE template constexpr decltype(auto) visit(_Visitor&&, _Variants&&...); template inline enable_if_t<(is_move_constructible_v<_Types> && ...) && (is_swappable_v<_Types> && ...)> swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } template enable_if_t && ...) && (is_swappable_v<_Types> && ...))> swap(variant<_Types...>&, variant<_Types...>&) = delete; class bad_variant_access : public exception { public: bad_variant_access() noexcept : _M_reason("Unknown reason") { } const char* what() const noexcept override { return _M_reason; } private: bad_variant_access(const char* __reason) : _M_reason(__reason) { } const char* _M_reason; friend void __throw_bad_variant_access(const char* __what); }; inline void __throw_bad_variant_access(const char* __what) { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); } template class variant : private __detail::__variant::_Variant_base<_Types...>, private _Enable_default_constructor< __detail::__variant::_Traits<_Types...>::_S_default_ctor, variant<_Types...>>, private _Enable_copy_move< __detail::__variant::_Traits<_Types...>::_S_copy_ctor, __detail::__variant::_Traits<_Types...>::_S_copy_assign, __detail::__variant::_Traits<_Types...>::_S_move_ctor, __detail::__variant::_Traits<_Types...>::_S_move_assign, variant<_Types...>> { private: static_assert(sizeof...(_Types) > 0, "variant must have at least one alternative"); static_assert(!(std::is_reference_v<_Types> || ...), "variant must have no reference alternative"); static_assert(!(std::is_void_v<_Types> || ...), "variant must have no void alternative"); using _Base = __detail::__variant::_Variant_base<_Types...>; using _Default_ctor_enabler = _Enable_default_constructor< __detail::__variant::_Traits<_Types...>::_S_default_ctor, variant<_Types...>>; template static constexpr bool __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>; template static constexpr size_t __accepted_index = __detail::__variant::__accepted_index<_Tp&&, variant>::value; template struct __to_type_impl; template struct __to_type_impl<_Np, true> { using type = variant_alternative_t<_Np, variant>; }; template using __to_type = typename __to_type_impl<_Np>::type; template using __accepted_type = __to_type<__accepted_index<_Tp>>; template static constexpr size_t __index_of = __detail::__variant::__index_of_v<_Tp, _Types...>; using _Traits = __detail::__variant::_Traits<_Types...>; template struct __is_in_place_tag : false_type { }; template struct __is_in_place_tag> : true_type { }; template struct __is_in_place_tag> : true_type { }; template static constexpr bool __not_in_place_tag = !__is_in_place_tag>::value; public: variant() = default; variant(const variant& __rhs) = default; variant(variant&&) = default; variant& operator=(const variant&) = default; variant& operator=(variant&&) = default; ~variant() = default; template, variant>>, typename = enable_if_t<(sizeof...(_Types)>0)>, typename = enable_if_t<__not_in_place_tag<_Tp>>, typename = enable_if_t<__exactly_once<__accepted_type<_Tp&&>> && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>>> constexpr variant(_Tp&& __t) noexcept(is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>) : variant(in_place_index<__accepted_index<_Tp&&>>, std::forward<_Tp>(__t)) { __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); } template && is_constructible_v<_Tp, _Args&&...>>> constexpr explicit variant(in_place_type_t<_Tp>, _Args&&... __args) : variant(in_place_index<__index_of<_Tp>>, std::forward<_Args>(__args)...) { __glibcxx_assert(holds_alternative<_Tp>(*this)); } template && is_constructible_v< _Tp, initializer_list<_Up>&, _Args&&...>>> constexpr explicit variant(in_place_type_t<_Tp>, initializer_list<_Up> __il, _Args&&... __args) : variant(in_place_index<__index_of<_Tp>>, __il, std::forward<_Args>(__args)...) { __glibcxx_assert(holds_alternative<_Tp>(*this)); } template, _Args&&...>>> constexpr explicit variant(in_place_index_t<_Np>, _Args&&... __args) : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...), _Default_ctor_enabler(_Enable_default_constructor_tag{}) { __glibcxx_assert(index() == _Np); } template, initializer_list<_Up>&, _Args&&...>>> constexpr explicit variant(in_place_index_t<_Np>, initializer_list<_Up> __il, _Args&&... __args) : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...), _Default_ctor_enabler(_Enable_default_constructor_tag{}) { __glibcxx_assert(index() == _Np); } template enable_if_t<__exactly_once<__accepted_type<_Tp&&>> && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&> && is_assignable_v<__accepted_type<_Tp&&>&, _Tp&&> && !is_same_v, variant>, variant&> operator=(_Tp&& __rhs) noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp&&> && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>) { constexpr auto __index = __accepted_index<_Tp&&>; if (index() == __index) std::get<__index>(*this) = std::forward<_Tp>(__rhs); else this->emplace<__index>(std::forward<_Tp>(__rhs)); __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); return *this; } template enable_if_t && __exactly_once<_Tp>, _Tp&> emplace(_Args&&... __args) { auto& ret = this->emplace<__index_of<_Tp>>(std::forward<_Args>(__args)...); __glibcxx_assert(holds_alternative<_Tp>(*this)); return ret; } template enable_if_t&, _Args...> && __exactly_once<_Tp>, _Tp&> emplace(initializer_list<_Up> __il, _Args&&... __args) { auto& ret = this->emplace<__index_of<_Tp>>(__il, std::forward<_Args>(__args)...); __glibcxx_assert(holds_alternative<_Tp>(*this)); return ret; } template enable_if_t, _Args...>, variant_alternative_t<_Np, variant>&> emplace(_Args&&... __args) { static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); this->~variant(); __try { ::new (this) variant(in_place_index<_Np>, std::forward<_Args>(__args)...); } __catch (...) { this->_M_index = variant_npos; __throw_exception_again; } __glibcxx_assert(index() == _Np); return std::get<_Np>(*this); } template enable_if_t, initializer_list<_Up>&, _Args...>, variant_alternative_t<_Np, variant>&> emplace(initializer_list<_Up> __il, _Args&&... __args) { static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); this->~variant(); __try { ::new (this) variant(in_place_index<_Np>, __il, std::forward<_Args>(__args)...); } __catch (...) { this->_M_index = variant_npos; __throw_exception_again; } __glibcxx_assert(index() == _Np); return std::get<_Np>(*this); } constexpr bool valueless_by_exception() const noexcept { return !this->_M_valid(); } constexpr size_t index() const noexcept { if (this->_M_index == typename _Base::__index_type(variant_npos)) return variant_npos; return this->_M_index; } void swap(variant& __rhs) noexcept((__is_nothrow_swappable<_Types>::value && ...) && is_nothrow_move_constructible_v) { if (this->index() == __rhs.index()) { if (this->_M_valid()) { static constexpr void (*_S_vtable[])(void*, void*) = { &__detail::__variant::__erased_swap<_Types&, _Types&>... }; _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage()); } } else if (!this->_M_valid()) { this->_M_destructive_move(std::move(__rhs)); __rhs._M_reset(); } else if (!__rhs._M_valid()) { __rhs._M_destructive_move(std::move(*this)); this->_M_reset(); } else { auto __tmp = std::move(__rhs); __rhs._M_destructive_move(std::move(*this)); this->_M_destructive_move(std::move(__tmp)); } } private: #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \ template \ static constexpr bool \ (*_S_erased_##__NAME[])(const variant&, const variant&) = \ { &__detail::__variant::__erased_##__NAME< \ const variant&, __indices>... }; \ template \ constexpr bool \ _M_##__NAME(const variant& __rhs, \ std::index_sequence<__indices...>) const \ { \ auto __lhs_index = this->index(); \ auto __rhs_index = __rhs.index(); \ if (__lhs_index != __rhs_index || valueless_by_exception()) \ /* Modulo addition. */ \ return __lhs_index + 1 __OP __rhs_index + 1; \ return _S_erased_##__NAME<__indices...>[__lhs_index](*this, __rhs); \ } _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less) _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal) _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater) #undef _VARIANT_RELATION_FUNCTION_TEMPLATE #ifdef __clang__ public: using _Base::_M_u; // See https://bugs.llvm.org/show_bug.cgi?id=31852 private: #endif template friend constexpr decltype(auto) __detail::__variant::__get(_Vp&& __v); template friend void* __detail::__variant::__get_storage(_Vp&& __v); #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \ template \ friend constexpr bool \ operator __OP(const variant<_Tp...>& __lhs, \ const variant<_Tp...>& __rhs); _VARIANT_RELATION_FUNCTION_TEMPLATE(<) _VARIANT_RELATION_FUNCTION_TEMPLATE(<=) _VARIANT_RELATION_FUNCTION_TEMPLATE(==) _VARIANT_RELATION_FUNCTION_TEMPLATE(!=) _VARIANT_RELATION_FUNCTION_TEMPLATE(>=) _VARIANT_RELATION_FUNCTION_TEMPLATE(>) #undef _VARIANT_RELATION_FUNCTION_TEMPLATE }; template constexpr variant_alternative_t<_Np, variant<_Types...>>& get(variant<_Types...>& __v) { static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); if (__v.index() != _Np) __throw_bad_variant_access("Unexpected index"); return __detail::__variant::__get<_Np>(__v); } template constexpr variant_alternative_t<_Np, variant<_Types...>>&& get(variant<_Types...>&& __v) { static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); if (__v.index() != _Np) __throw_bad_variant_access("Unexpected index"); return __detail::__variant::__get<_Np>(std::move(__v)); } template constexpr const variant_alternative_t<_Np, variant<_Types...>>& get(const variant<_Types...>& __v) { static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); if (__v.index() != _Np) __throw_bad_variant_access("Unexpected index"); return __detail::__variant::__get<_Np>(__v); } template constexpr const variant_alternative_t<_Np, variant<_Types...>>&& get(const variant<_Types...>&& __v) { static_assert(_Np < sizeof...(_Types), "The index should be in [0, number of alternatives)"); if (__v.index() != _Np) __throw_bad_variant_access("Unexpected index"); return __detail::__variant::__get<_Np>(std::move(__v)); } template constexpr decltype(auto) visit(_Visitor&& __visitor, _Variants&&... __variants) { if ((__variants.valueless_by_exception() || ...)) __throw_bad_variant_access("Unexpected index"); using _Result_type = decltype(std::forward<_Visitor>(__visitor)( std::get<0>(std::forward<_Variants>(__variants))...)); constexpr auto& __vtable = __detail::__variant::__gen_vtable< _Result_type, _Visitor&&, _Variants&&...>::_S_vtable; auto __func_ptr = __vtable._M_access(__variants.index()...); return (*__func_ptr)(std::forward<_Visitor>(__visitor), std::forward<_Variants>(__variants)...); } template struct __variant_hash_call_base_impl { size_t operator()(const variant<_Types...>& __t) const noexcept((is_nothrow_invocable_v>, _Types> && ...)) { if (!__t.valueless_by_exception()) { namespace __edv = __detail::__variant; static constexpr size_t (*_S_vtable[])(void*) = { &__edv::__erased_hash... }; return hash{}(__t.index()) + _S_vtable[__t.index()](__edv::__get_storage(__t)); } return hash{}(__t.index()); } }; template struct __variant_hash_call_base_impl {}; template using __variant_hash_call_base = __variant_hash_call_base_impl<(__poison_hash>:: __enable_hash_call &&...), _Types...>; template struct hash> : private __detail::__variant::_Variant_hash_base< variant<_Types...>, std::index_sequence_for<_Types...>>, public __variant_hash_call_base<_Types...> { using result_type [[__deprecated__]] = size_t; using argument_type [[__deprecated__]] = variant<_Types...>; }; template<> struct hash { using result_type [[__deprecated__]] = size_t; using argument_type [[__deprecated__]] = monostate; size_t operator()(const monostate& __t) const noexcept { constexpr size_t __magic_monostate_hash = -7777; return __magic_monostate_hash; } }; template struct __is_fast_hash>> : bool_constant<(__is_fast_hash<_Types>::value && ...)> { }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++17 #endif // _GLIBCXX_VARIANT 8/ratio000064400000046656152526447520006011 0ustar00// ratio -*- C++ -*- // Copyright (C) 2008-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/ratio * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_RATIO #define _GLIBCXX_RATIO 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup ratio Rational Arithmetic * @ingroup utilities * * Compile time representation of finite rational numbers. * @{ */ template struct __static_sign : integral_constant { }; template struct __static_abs : integral_constant::value> { }; template struct __static_gcd : __static_gcd<_Qn, (_Pn % _Qn)> { }; template struct __static_gcd<_Pn, 0> : integral_constant::value> { }; template struct __static_gcd<0, _Qn> : integral_constant::value> { }; // Let c = 2^(half # of bits in an intmax_t) // then we find a1, a0, b1, b0 s.t. N = a1*c + a0, M = b1*c + b0 // The multiplication of N and M becomes, // N * M = (a1 * b1)c^2 + (a0 * b1 + b0 * a1)c + a0 * b0 // Multiplication is safe if each term and the sum of the terms // is representable by intmax_t. template struct __safe_multiply { private: static const uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4); static const uintmax_t __a0 = __static_abs<_Pn>::value % __c; static const uintmax_t __a1 = __static_abs<_Pn>::value / __c; static const uintmax_t __b0 = __static_abs<_Qn>::value % __c; static const uintmax_t __b1 = __static_abs<_Qn>::value / __c; static_assert(__a1 == 0 || __b1 == 0, "overflow in multiplication"); static_assert(__a0 * __b1 + __b0 * __a1 < (__c >> 1), "overflow in multiplication"); static_assert(__b0 * __a0 <= __INTMAX_MAX__, "overflow in multiplication"); static_assert((__a0 * __b1 + __b0 * __a1) * __c <= __INTMAX_MAX__ - __b0 * __a0, "overflow in multiplication"); public: static const intmax_t value = _Pn * _Qn; }; // Some double-precision utilities, where numbers are represented as // __hi*2^(8*sizeof(uintmax_t)) + __lo. template struct __big_less : integral_constant { }; template struct __big_add { static constexpr uintmax_t __lo = __lo1 + __lo2; static constexpr uintmax_t __hi = (__hi1 + __hi2 + (__lo1 + __lo2 < __lo1)); // carry }; // Subtract a number from a bigger one. template struct __big_sub { static_assert(!__big_less<__hi1, __lo1, __hi2, __lo2>::value, "Internal library error"); static constexpr uintmax_t __lo = __lo1 - __lo2; static constexpr uintmax_t __hi = (__hi1 - __hi2 - (__lo1 < __lo2)); // carry }; // Same principle as __safe_multiply. template struct __big_mul { private: static constexpr uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4); static constexpr uintmax_t __x0 = __x % __c; static constexpr uintmax_t __x1 = __x / __c; static constexpr uintmax_t __y0 = __y % __c; static constexpr uintmax_t __y1 = __y / __c; static constexpr uintmax_t __x0y0 = __x0 * __y0; static constexpr uintmax_t __x0y1 = __x0 * __y1; static constexpr uintmax_t __x1y0 = __x1 * __y0; static constexpr uintmax_t __x1y1 = __x1 * __y1; static constexpr uintmax_t __mix = __x0y1 + __x1y0; // possible carry... static constexpr uintmax_t __mix_lo = __mix * __c; static constexpr uintmax_t __mix_hi = __mix / __c + ((__mix < __x0y1) ? __c : 0); // ... added here typedef __big_add<__mix_hi, __mix_lo, __x1y1, __x0y0> _Res; public: static constexpr uintmax_t __hi = _Res::__hi; static constexpr uintmax_t __lo = _Res::__lo; }; // Adapted from __udiv_qrnnd_c in longlong.h // This version assumes that the high bit of __d is 1. template struct __big_div_impl { private: static_assert(__d >= (uintmax_t(1) << (sizeof(intmax_t) * 8 - 1)), "Internal library error"); static_assert(__n1 < __d, "Internal library error"); static constexpr uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4); static constexpr uintmax_t __d1 = __d / __c; static constexpr uintmax_t __d0 = __d % __c; static constexpr uintmax_t __q1x = __n1 / __d1; static constexpr uintmax_t __r1x = __n1 % __d1; static constexpr uintmax_t __m = __q1x * __d0; static constexpr uintmax_t __r1y = __r1x * __c + __n0 / __c; static constexpr uintmax_t __r1z = __r1y + __d; static constexpr uintmax_t __r1 = ((__r1y < __m) ? ((__r1z >= __d) && (__r1z < __m)) ? (__r1z + __d) : __r1z : __r1y) - __m; static constexpr uintmax_t __q1 = __q1x - ((__r1y < __m) ? ((__r1z >= __d) && (__r1z < __m)) ? 2 : 1 : 0); static constexpr uintmax_t __q0x = __r1 / __d1; static constexpr uintmax_t __r0x = __r1 % __d1; static constexpr uintmax_t __n = __q0x * __d0; static constexpr uintmax_t __r0y = __r0x * __c + __n0 % __c; static constexpr uintmax_t __r0z = __r0y + __d; static constexpr uintmax_t __r0 = ((__r0y < __n) ? ((__r0z >= __d) && (__r0z < __n)) ? (__r0z + __d) : __r0z : __r0y) - __n; static constexpr uintmax_t __q0 = __q0x - ((__r0y < __n) ? ((__r0z >= __d) && (__r0z < __n)) ? 2 : 1 : 0); public: static constexpr uintmax_t __quot = __q1 * __c + __q0; static constexpr uintmax_t __rem = __r0; private: typedef __big_mul<__quot, __d> _Prod; typedef __big_add<_Prod::__hi, _Prod::__lo, 0, __rem> _Sum; static_assert(_Sum::__hi == __n1 && _Sum::__lo == __n0, "Internal library error"); }; template struct __big_div { private: static_assert(__d != 0, "Internal library error"); static_assert(sizeof (uintmax_t) == sizeof (unsigned long long), "This library calls __builtin_clzll on uintmax_t, which " "is unsafe on your platform. Please complain to " "http://gcc.gnu.org/bugzilla/"); static constexpr int __shift = __builtin_clzll(__d); static constexpr int __coshift_ = sizeof(uintmax_t) * 8 - __shift; static constexpr int __coshift = (__shift != 0) ? __coshift_ : 0; static constexpr uintmax_t __c1 = uintmax_t(1) << __shift; static constexpr uintmax_t __c2 = uintmax_t(1) << __coshift; static constexpr uintmax_t __new_d = __d * __c1; static constexpr uintmax_t __new_n0 = __n0 * __c1; static constexpr uintmax_t __n1_shifted = (__n1 % __d) * __c1; static constexpr uintmax_t __n0_top = (__shift != 0) ? (__n0 / __c2) : 0; static constexpr uintmax_t __new_n1 = __n1_shifted + __n0_top; typedef __big_div_impl<__new_n1, __new_n0, __new_d> _Res; public: static constexpr uintmax_t __quot_hi = __n1 / __d; static constexpr uintmax_t __quot_lo = _Res::__quot; static constexpr uintmax_t __rem = _Res::__rem / __c1; private: typedef __big_mul<__quot_lo, __d> _P0; typedef __big_mul<__quot_hi, __d> _P1; typedef __big_add<_P0::__hi, _P0::__lo, _P1::__lo, __rem> _Sum; // No overflow. static_assert(_P1::__hi == 0, "Internal library error"); static_assert(_Sum::__hi >= _P0::__hi, "Internal library error"); // Matches the input data. static_assert(_Sum::__hi == __n1 && _Sum::__lo == __n0, "Internal library error"); static_assert(__rem < __d, "Internal library error"); }; /** * @brief Provides compile-time rational arithmetic. * * This class template represents any finite rational number with a * numerator and denominator representable by compile-time constants of * type intmax_t. The ratio is simplified when instantiated. * * For example: * @code * std::ratio<7,-21>::num == -1; * std::ratio<7,-21>::den == 3; * @endcode * */ template struct ratio { static_assert(_Den != 0, "denominator cannot be zero"); static_assert(_Num >= -__INTMAX_MAX__ && _Den >= -__INTMAX_MAX__, "out of range"); // Note: sign(N) * abs(N) == N static constexpr intmax_t num = _Num * __static_sign<_Den>::value / __static_gcd<_Num, _Den>::value; static constexpr intmax_t den = __static_abs<_Den>::value / __static_gcd<_Num, _Den>::value; typedef ratio type; }; template constexpr intmax_t ratio<_Num, _Den>::num; template constexpr intmax_t ratio<_Num, _Den>::den; template struct __ratio_multiply { private: static const intmax_t __gcd1 = __static_gcd<_R1::num, _R2::den>::value; static const intmax_t __gcd2 = __static_gcd<_R2::num, _R1::den>::value; public: typedef ratio< __safe_multiply<(_R1::num / __gcd1), (_R2::num / __gcd2)>::value, __safe_multiply<(_R1::den / __gcd2), (_R2::den / __gcd1)>::value> type; static constexpr intmax_t num = type::num; static constexpr intmax_t den = type::den; }; template constexpr intmax_t __ratio_multiply<_R1, _R2>::num; template constexpr intmax_t __ratio_multiply<_R1, _R2>::den; /// ratio_multiply template using ratio_multiply = typename __ratio_multiply<_R1, _R2>::type; template struct __ratio_divide { static_assert(_R2::num != 0, "division by 0"); typedef typename __ratio_multiply< _R1, ratio<_R2::den, _R2::num>>::type type; static constexpr intmax_t num = type::num; static constexpr intmax_t den = type::den; }; template constexpr intmax_t __ratio_divide<_R1, _R2>::num; template constexpr intmax_t __ratio_divide<_R1, _R2>::den; /// ratio_divide template using ratio_divide = typename __ratio_divide<_R1, _R2>::type; /// ratio_equal template struct ratio_equal : integral_constant { }; /// ratio_not_equal template struct ratio_not_equal : integral_constant::value> { }; // Both numbers are positive. template, typename _Right = __big_mul<_R2::num,_R1::den> > struct __ratio_less_impl_1 : integral_constant::value> { }; template::value != __static_sign<_R2::num>::value)), bool = (__static_sign<_R1::num>::value == -1 && __static_sign<_R2::num>::value == -1)> struct __ratio_less_impl : __ratio_less_impl_1<_R1, _R2>::type { }; template struct __ratio_less_impl<_R1, _R2, true, false> : integral_constant { }; template struct __ratio_less_impl<_R1, _R2, false, true> : __ratio_less_impl_1, ratio<-_R1::num, _R1::den> >::type { }; /// ratio_less template struct ratio_less : __ratio_less_impl<_R1, _R2>::type { }; /// ratio_less_equal template struct ratio_less_equal : integral_constant::value> { }; /// ratio_greater template struct ratio_greater : integral_constant::value> { }; /// ratio_greater_equal template struct ratio_greater_equal : integral_constant::value> { }; #if __cplusplus > 201402L template inline constexpr bool ratio_equal_v = ratio_equal<_R1, _R2>::value; template inline constexpr bool ratio_not_equal_v = ratio_not_equal<_R1, _R2>::value; template inline constexpr bool ratio_less_v = ratio_less<_R1, _R2>::value; template inline constexpr bool ratio_less_equal_v = ratio_less_equal<_R1, _R2>::value; template inline constexpr bool ratio_greater_v = ratio_greater<_R1, _R2>::value; template inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<_R1, _R2>::value; #endif // C++17 template= 0), bool = (_R2::num >= 0), bool = ratio_less::value, _R1::den>, ratio<__static_abs<_R2::num>::value, _R2::den> >::value> struct __ratio_add_impl { private: typedef typename __ratio_add_impl< ratio<-_R1::num, _R1::den>, ratio<-_R2::num, _R2::den> >::type __t; public: typedef ratio<-__t::num, __t::den> type; }; // True addition of nonnegative numbers. template struct __ratio_add_impl<_R1, _R2, true, true, __b> { private: static constexpr uintmax_t __g = __static_gcd<_R1::den, _R2::den>::value; static constexpr uintmax_t __d2 = _R2::den / __g; typedef __big_mul<_R1::den, __d2> __d; typedef __big_mul<_R1::num, _R2::den / __g> __x; typedef __big_mul<_R2::num, _R1::den / __g> __y; typedef __big_add<__x::__hi, __x::__lo, __y::__hi, __y::__lo> __n; static_assert(__n::__hi >= __x::__hi, "Internal library error"); typedef __big_div<__n::__hi, __n::__lo, __g> __ng; static constexpr uintmax_t __g2 = __static_gcd<__ng::__rem, __g>::value; typedef __big_div<__n::__hi, __n::__lo, __g2> __n_final; static_assert(__n_final::__rem == 0, "Internal library error"); static_assert(__n_final::__quot_hi == 0 && __n_final::__quot_lo <= __INTMAX_MAX__, "overflow in addition"); typedef __big_mul<_R1::den / __g2, __d2> __d_final; static_assert(__d_final::__hi == 0 && __d_final::__lo <= __INTMAX_MAX__, "overflow in addition"); public: typedef ratio<__n_final::__quot_lo, __d_final::__lo> type; }; template struct __ratio_add_impl<_R1, _R2, false, true, true> : __ratio_add_impl<_R2, _R1> { }; // True subtraction of nonnegative numbers yielding a nonnegative result. template struct __ratio_add_impl<_R1, _R2, true, false, false> { private: static constexpr uintmax_t __g = __static_gcd<_R1::den, _R2::den>::value; static constexpr uintmax_t __d2 = _R2::den / __g; typedef __big_mul<_R1::den, __d2> __d; typedef __big_mul<_R1::num, _R2::den / __g> __x; typedef __big_mul<-_R2::num, _R1::den / __g> __y; typedef __big_sub<__x::__hi, __x::__lo, __y::__hi, __y::__lo> __n; typedef __big_div<__n::__hi, __n::__lo, __g> __ng; static constexpr uintmax_t __g2 = __static_gcd<__ng::__rem, __g>::value; typedef __big_div<__n::__hi, __n::__lo, __g2> __n_final; static_assert(__n_final::__rem == 0, "Internal library error"); static_assert(__n_final::__quot_hi == 0 && __n_final::__quot_lo <= __INTMAX_MAX__, "overflow in addition"); typedef __big_mul<_R1::den / __g2, __d2> __d_final; static_assert(__d_final::__hi == 0 && __d_final::__lo <= __INTMAX_MAX__, "overflow in addition"); public: typedef ratio<__n_final::__quot_lo, __d_final::__lo> type; }; template struct __ratio_add { typedef typename __ratio_add_impl<_R1, _R2>::type type; static constexpr intmax_t num = type::num; static constexpr intmax_t den = type::den; }; template constexpr intmax_t __ratio_add<_R1, _R2>::num; template constexpr intmax_t __ratio_add<_R1, _R2>::den; /// ratio_add template using ratio_add = typename __ratio_add<_R1, _R2>::type; template struct __ratio_subtract { typedef typename __ratio_add< _R1, ratio<-_R2::num, _R2::den>>::type type; static constexpr intmax_t num = type::num; static constexpr intmax_t den = type::den; }; template constexpr intmax_t __ratio_subtract<_R1, _R2>::num; template constexpr intmax_t __ratio_subtract<_R1, _R2>::den; /// ratio_subtract template using ratio_subtract = typename __ratio_subtract<_R1, _R2>::type; typedef ratio<1, 1000000000000000000> atto; typedef ratio<1, 1000000000000000> femto; typedef ratio<1, 1000000000000> pico; typedef ratio<1, 1000000000> nano; typedef ratio<1, 1000000> micro; typedef ratio<1, 1000> milli; typedef ratio<1, 100> centi; typedef ratio<1, 10> deci; typedef ratio< 10, 1> deca; typedef ratio< 100, 1> hecto; typedef ratio< 1000, 1> kilo; typedef ratio< 1000000, 1> mega; typedef ratio< 1000000000, 1> giga; typedef ratio< 1000000000000, 1> tera; typedef ratio< 1000000000000000, 1> peta; typedef ratio< 1000000000000000000, 1> exa; // @} group ratio _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif //_GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif //_GLIBCXX_RATIO 8/cmath000064400000136016152526447520005755 0ustar00// -*- C++ -*- C forwarding header. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/cmath * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c math.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 26.5 C library // #pragma GCC system_header #include #include #include #define _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include_next #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include #ifndef _GLIBCXX_CMATH #define _GLIBCXX_CMATH 1 // Get rid of those macros defined in in lieu of real functions. #undef div #undef acos #undef asin #undef atan #undef atan2 #undef ceil #undef cos #undef cosh #undef exp #undef fabs #undef floor #undef fmod #undef frexp #undef ldexp #undef log #undef log10 #undef modf #undef pow #undef sin #undef sinh #undef sqrt #undef tan #undef tanh extern "C++" { namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::acos; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float acos(float __x) { return __builtin_acosf(__x); } inline _GLIBCXX_CONSTEXPR long double acos(long double __x) { return __builtin_acosl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type acos(_Tp __x) { return __builtin_acos(__x); } using ::asin; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float asin(float __x) { return __builtin_asinf(__x); } inline _GLIBCXX_CONSTEXPR long double asin(long double __x) { return __builtin_asinl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type asin(_Tp __x) { return __builtin_asin(__x); } using ::atan; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float atan(float __x) { return __builtin_atanf(__x); } inline _GLIBCXX_CONSTEXPR long double atan(long double __x) { return __builtin_atanl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type atan(_Tp __x) { return __builtin_atan(__x); } using ::atan2; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float atan2(float __y, float __x) { return __builtin_atan2f(__y, __x); } inline _GLIBCXX_CONSTEXPR long double atan2(long double __y, long double __x) { return __builtin_atan2l(__y, __x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__promote_2<_Tp, _Up>::__type atan2(_Tp __y, _Up __x) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return atan2(__type(__y), __type(__x)); } using ::ceil; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float ceil(float __x) { return __builtin_ceilf(__x); } inline _GLIBCXX_CONSTEXPR long double ceil(long double __x) { return __builtin_ceill(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type ceil(_Tp __x) { return __builtin_ceil(__x); } using ::cos; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float cos(float __x) { return __builtin_cosf(__x); } inline _GLIBCXX_CONSTEXPR long double cos(long double __x) { return __builtin_cosl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type cos(_Tp __x) { return __builtin_cos(__x); } using ::cosh; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float cosh(float __x) { return __builtin_coshf(__x); } inline _GLIBCXX_CONSTEXPR long double cosh(long double __x) { return __builtin_coshl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type cosh(_Tp __x) { return __builtin_cosh(__x); } using ::exp; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float exp(float __x) { return __builtin_expf(__x); } inline _GLIBCXX_CONSTEXPR long double exp(long double __x) { return __builtin_expl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type exp(_Tp __x) { return __builtin_exp(__x); } using ::fabs; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float fabs(float __x) { return __builtin_fabsf(__x); } inline _GLIBCXX_CONSTEXPR long double fabs(long double __x) { return __builtin_fabsl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type fabs(_Tp __x) { return __builtin_fabs(__x); } using ::floor; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float floor(float __x) { return __builtin_floorf(__x); } inline _GLIBCXX_CONSTEXPR long double floor(long double __x) { return __builtin_floorl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type floor(_Tp __x) { return __builtin_floor(__x); } using ::fmod; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float fmod(float __x, float __y) { return __builtin_fmodf(__x, __y); } inline _GLIBCXX_CONSTEXPR long double fmod(long double __x, long double __y) { return __builtin_fmodl(__x, __y); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__promote_2<_Tp, _Up>::__type fmod(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return fmod(__type(__x), __type(__y)); } using ::frexp; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline float frexp(float __x, int* __exp) { return __builtin_frexpf(__x, __exp); } inline long double frexp(long double __x, int* __exp) { return __builtin_frexpl(__x, __exp); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type frexp(_Tp __x, int* __exp) { return __builtin_frexp(__x, __exp); } using ::ldexp; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float ldexp(float __x, int __exp) { return __builtin_ldexpf(__x, __exp); } inline _GLIBCXX_CONSTEXPR long double ldexp(long double __x, int __exp) { return __builtin_ldexpl(__x, __exp); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type ldexp(_Tp __x, int __exp) { return __builtin_ldexp(__x, __exp); } using ::log; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float log(float __x) { return __builtin_logf(__x); } inline _GLIBCXX_CONSTEXPR long double log(long double __x) { return __builtin_logl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log(_Tp __x) { return __builtin_log(__x); } using ::log10; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float log10(float __x) { return __builtin_log10f(__x); } inline _GLIBCXX_CONSTEXPR long double log10(long double __x) { return __builtin_log10l(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log10(_Tp __x) { return __builtin_log10(__x); } using ::modf; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline float modf(float __x, float* __iptr) { return __builtin_modff(__x, __iptr); } inline long double modf(long double __x, long double* __iptr) { return __builtin_modfl(__x, __iptr); } #endif using ::pow; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float pow(float __x, float __y) { return __builtin_powf(__x, __y); } inline _GLIBCXX_CONSTEXPR long double pow(long double __x, long double __y) { return __builtin_powl(__x, __y); } #if __cplusplus < 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 550. What should the return type of pow(float,int) be? inline double pow(double __x, int __i) { return __builtin_powi(__x, __i); } inline float pow(float __x, int __n) { return __builtin_powif(__x, __n); } inline long double pow(long double __x, int __n) { return __builtin_powil(__x, __n); } #endif #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__promote_2<_Tp, _Up>::__type pow(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return pow(__type(__x), __type(__y)); } using ::sin; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float sin(float __x) { return __builtin_sinf(__x); } inline _GLIBCXX_CONSTEXPR long double sin(long double __x) { return __builtin_sinl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type sin(_Tp __x) { return __builtin_sin(__x); } using ::sinh; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float sinh(float __x) { return __builtin_sinhf(__x); } inline _GLIBCXX_CONSTEXPR long double sinh(long double __x) { return __builtin_sinhl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type sinh(_Tp __x) { return __builtin_sinh(__x); } using ::sqrt; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float sqrt(float __x) { return __builtin_sqrtf(__x); } inline _GLIBCXX_CONSTEXPR long double sqrt(long double __x) { return __builtin_sqrtl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type sqrt(_Tp __x) { return __builtin_sqrt(__x); } using ::tan; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float tan(float __x) { return __builtin_tanf(__x); } inline _GLIBCXX_CONSTEXPR long double tan(long double __x) { return __builtin_tanl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type tan(_Tp __x) { return __builtin_tan(__x); } using ::tanh; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float tanh(float __x) { return __builtin_tanhf(__x); } inline _GLIBCXX_CONSTEXPR long double tanh(long double __x) { return __builtin_tanhl(__x); } #endif template inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type tanh(_Tp __x) { return __builtin_tanh(__x); } #if _GLIBCXX_USE_C99_MATH #if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC // These are possible macros imported from C99-land. #undef fpclassify #undef isfinite #undef isinf #undef isnan #undef isnormal #undef signbit #undef isgreater #undef isgreaterequal #undef isless #undef islessequal #undef islessgreater #undef isunordered #if __cplusplus >= 201103L #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr int fpclassify(float __x) { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); } constexpr int fpclassify(double __x) { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); } constexpr int fpclassify(long double __x) { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, int>::__type fpclassify(_Tp __x) { return __x != 0 ? FP_NORMAL : FP_ZERO; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isfinite(float __x) { return __builtin_isfinite(__x); } constexpr bool isfinite(double __x) { return __builtin_isfinite(__x); } constexpr bool isfinite(long double __x) { return __builtin_isfinite(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type isfinite(_Tp __x) { return true; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isinf(float __x) { return __builtin_isinf(__x); } #if _GLIBCXX_HAVE_OBSOLETE_ISINF \ && !_GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC using ::isinf; #else constexpr bool isinf(double __x) { return __builtin_isinf(__x); } #endif constexpr bool isinf(long double __x) { return __builtin_isinf(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type isinf(_Tp __x) { return false; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isnan(float __x) { return __builtin_isnan(__x); } #if _GLIBCXX_HAVE_OBSOLETE_ISNAN \ && !_GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC using ::isnan; #else constexpr bool isnan(double __x) { return __builtin_isnan(__x); } #endif constexpr bool isnan(long double __x) { return __builtin_isnan(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type isnan(_Tp __x) { return false; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isnormal(float __x) { return __builtin_isnormal(__x); } constexpr bool isnormal(double __x) { return __builtin_isnormal(__x); } constexpr bool isnormal(long double __x) { return __builtin_isnormal(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type isnormal(_Tp __x) { return __x != 0 ? true : false; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP // Note: middle-end/36757 is fixed, __builtin_signbit is type-generic. constexpr bool signbit(float __x) { return __builtin_signbit(__x); } constexpr bool signbit(double __x) { return __builtin_signbit(__x); } constexpr bool signbit(long double __x) { return __builtin_signbit(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type signbit(_Tp __x) { return __x < 0 ? true : false; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isgreater(float __x, float __y) { return __builtin_isgreater(__x, __y); } constexpr bool isgreater(double __x, double __y) { return __builtin_isgreater(__x, __y); } constexpr bool isgreater(long double __x, long double __y) { return __builtin_isgreater(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type isgreater(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_isgreater(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isgreaterequal(float __x, float __y) { return __builtin_isgreaterequal(__x, __y); } constexpr bool isgreaterequal(double __x, double __y) { return __builtin_isgreaterequal(__x, __y); } constexpr bool isgreaterequal(long double __x, long double __y) { return __builtin_isgreaterequal(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type isgreaterequal(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_isgreaterequal(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isless(float __x, float __y) { return __builtin_isless(__x, __y); } constexpr bool isless(double __x, double __y) { return __builtin_isless(__x, __y); } constexpr bool isless(long double __x, long double __y) { return __builtin_isless(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type isless(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_isless(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool islessequal(float __x, float __y) { return __builtin_islessequal(__x, __y); } constexpr bool islessequal(double __x, double __y) { return __builtin_islessequal(__x, __y); } constexpr bool islessequal(long double __x, long double __y) { return __builtin_islessequal(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type islessequal(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_islessequal(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool islessgreater(float __x, float __y) { return __builtin_islessgreater(__x, __y); } constexpr bool islessgreater(double __x, double __y) { return __builtin_islessgreater(__x, __y); } constexpr bool islessgreater(long double __x, long double __y) { return __builtin_islessgreater(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type islessgreater(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_islessgreater(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isunordered(float __x, float __y) { return __builtin_isunordered(__x, __y); } constexpr bool isunordered(double __x, double __y) { return __builtin_isunordered(__x, __y); } constexpr bool isunordered(long double __x, long double __y) { return __builtin_isunordered(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type isunordered(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_isunordered(__type(__x), __type(__y)); } #endif #else template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type fpclassify(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isfinite(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isfinite(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isinf(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isinf(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isnan(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isnan(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isnormal(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isnormal(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type signbit(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_signbit(__type(__f)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isgreater(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isgreater(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isgreaterequal(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isgreaterequal(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isless(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isless(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type islessequal(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_islessequal(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type islessgreater(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_islessgreater(__type(__f1), __type(__f2)); } template inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isunordered(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isunordered(__type(__f1), __type(__f2)); } #endif // C++11 #endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */ #endif /* _GLIBCXX_USE_C99_MATH */ #if __cplusplus >= 201103L #ifdef _GLIBCXX_USE_C99_MATH_TR1 #undef acosh #undef acoshf #undef acoshl #undef asinh #undef asinhf #undef asinhl #undef atanh #undef atanhf #undef atanhl #undef cbrt #undef cbrtf #undef cbrtl #undef copysign #undef copysignf #undef copysignl #undef erf #undef erff #undef erfl #undef erfc #undef erfcf #undef erfcl #undef exp2 #undef exp2f #undef exp2l #undef expm1 #undef expm1f #undef expm1l #undef fdim #undef fdimf #undef fdiml #undef fma #undef fmaf #undef fmal #undef fmax #undef fmaxf #undef fmaxl #undef fmin #undef fminf #undef fminl #undef hypot #undef hypotf #undef hypotl #undef ilogb #undef ilogbf #undef ilogbl #undef lgamma #undef lgammaf #undef lgammal #ifndef _GLIBCXX_NO_C99_ROUNDING_FUNCS #undef llrint #undef llrintf #undef llrintl #undef llround #undef llroundf #undef llroundl #endif #undef log1p #undef log1pf #undef log1pl #undef log2 #undef log2f #undef log2l #undef logb #undef logbf #undef logbl #undef lrint #undef lrintf #undef lrintl #undef lround #undef lroundf #undef lroundl #undef nan #undef nanf #undef nanl #undef nearbyint #undef nearbyintf #undef nearbyintl #undef nextafter #undef nextafterf #undef nextafterl #undef nexttoward #undef nexttowardf #undef nexttowardl #undef remainder #undef remainderf #undef remainderl #undef remquo #undef remquof #undef remquol #undef rint #undef rintf #undef rintl #undef round #undef roundf #undef roundl #undef scalbln #undef scalblnf #undef scalblnl #undef scalbn #undef scalbnf #undef scalbnl #undef tgamma #undef tgammaf #undef tgammal #undef trunc #undef truncf #undef truncl // types using ::double_t; using ::float_t; // functions using ::acosh; using ::acoshf; using ::acoshl; using ::asinh; using ::asinhf; using ::asinhl; using ::atanh; using ::atanhf; using ::atanhl; using ::cbrt; using ::cbrtf; using ::cbrtl; using ::copysign; using ::copysignf; using ::copysignl; using ::erf; using ::erff; using ::erfl; using ::erfc; using ::erfcf; using ::erfcl; using ::exp2; using ::exp2f; using ::exp2l; using ::expm1; using ::expm1f; using ::expm1l; using ::fdim; using ::fdimf; using ::fdiml; using ::fma; using ::fmaf; using ::fmal; using ::fmax; using ::fmaxf; using ::fmaxl; using ::fmin; using ::fminf; using ::fminl; using ::hypot; using ::hypotf; using ::hypotl; using ::ilogb; using ::ilogbf; using ::ilogbl; using ::lgamma; using ::lgammaf; using ::lgammal; #ifndef _GLIBCXX_NO_C99_ROUNDING_FUNCS using ::llrint; using ::llrintf; using ::llrintl; using ::llround; using ::llroundf; using ::llroundl; #endif using ::log1p; using ::log1pf; using ::log1pl; using ::log2; using ::log2f; using ::log2l; using ::logb; using ::logbf; using ::logbl; using ::lrint; using ::lrintf; using ::lrintl; using ::lround; using ::lroundf; using ::lroundl; using ::nan; using ::nanf; using ::nanl; using ::nearbyint; using ::nearbyintf; using ::nearbyintl; using ::nextafter; using ::nextafterf; using ::nextafterl; using ::nexttoward; using ::nexttowardf; using ::nexttowardl; using ::remainder; using ::remainderf; using ::remainderl; using ::remquo; using ::remquof; using ::remquol; using ::rint; using ::rintf; using ::rintl; using ::round; using ::roundf; using ::roundl; using ::scalbln; using ::scalblnf; using ::scalblnl; using ::scalbn; using ::scalbnf; using ::scalbnl; using ::tgamma; using ::tgammaf; using ::tgammal; using ::trunc; using ::truncf; using ::truncl; /// Additional overloads. #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float acosh(float __x) { return __builtin_acoshf(__x); } constexpr long double acosh(long double __x) { return __builtin_acoshl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type acosh(_Tp __x) { return __builtin_acosh(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float asinh(float __x) { return __builtin_asinhf(__x); } constexpr long double asinh(long double __x) { return __builtin_asinhl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type asinh(_Tp __x) { return __builtin_asinh(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float atanh(float __x) { return __builtin_atanhf(__x); } constexpr long double atanh(long double __x) { return __builtin_atanhl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type atanh(_Tp __x) { return __builtin_atanh(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float cbrt(float __x) { return __builtin_cbrtf(__x); } constexpr long double cbrt(long double __x) { return __builtin_cbrtl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type cbrt(_Tp __x) { return __builtin_cbrt(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float copysign(float __x, float __y) { return __builtin_copysignf(__x, __y); } constexpr long double copysign(long double __x, long double __y) { return __builtin_copysignl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type copysign(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return copysign(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float erf(float __x) { return __builtin_erff(__x); } constexpr long double erf(long double __x) { return __builtin_erfl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type erf(_Tp __x) { return __builtin_erf(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float erfc(float __x) { return __builtin_erfcf(__x); } constexpr long double erfc(long double __x) { return __builtin_erfcl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type erfc(_Tp __x) { return __builtin_erfc(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float exp2(float __x) { return __builtin_exp2f(__x); } constexpr long double exp2(long double __x) { return __builtin_exp2l(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type exp2(_Tp __x) { return __builtin_exp2(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float expm1(float __x) { return __builtin_expm1f(__x); } constexpr long double expm1(long double __x) { return __builtin_expm1l(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type expm1(_Tp __x) { return __builtin_expm1(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fdim(float __x, float __y) { return __builtin_fdimf(__x, __y); } constexpr long double fdim(long double __x, long double __y) { return __builtin_fdiml(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type fdim(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return fdim(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fma(float __x, float __y, float __z) { return __builtin_fmaf(__x, __y, __z); } constexpr long double fma(long double __x, long double __y, long double __z) { return __builtin_fmal(__x, __y, __z); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type fma(_Tp __x, _Up __y, _Vp __z) { typedef typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type __type; return fma(__type(__x), __type(__y), __type(__z)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fmax(float __x, float __y) { return __builtin_fmaxf(__x, __y); } constexpr long double fmax(long double __x, long double __y) { return __builtin_fmaxl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type fmax(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return fmax(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fmin(float __x, float __y) { return __builtin_fminf(__x, __y); } constexpr long double fmin(long double __x, long double __y) { return __builtin_fminl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type fmin(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return fmin(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float hypot(float __x, float __y) { return __builtin_hypotf(__x, __y); } constexpr long double hypot(long double __x, long double __y) { return __builtin_hypotl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type hypot(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return hypot(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr int ilogb(float __x) { return __builtin_ilogbf(__x); } constexpr int ilogb(long double __x) { return __builtin_ilogbl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, int>::__type ilogb(_Tp __x) { return __builtin_ilogb(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float lgamma(float __x) { return __builtin_lgammaf(__x); } constexpr long double lgamma(long double __x) { return __builtin_lgammal(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type lgamma(_Tp __x) { return __builtin_lgamma(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr long long llrint(float __x) { return __builtin_llrintf(__x); } constexpr long long llrint(long double __x) { return __builtin_llrintl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, long long>::__type llrint(_Tp __x) { return __builtin_llrint(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr long long llround(float __x) { return __builtin_llroundf(__x); } constexpr long long llround(long double __x) { return __builtin_llroundl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, long long>::__type llround(_Tp __x) { return __builtin_llround(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float log1p(float __x) { return __builtin_log1pf(__x); } constexpr long double log1p(long double __x) { return __builtin_log1pl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log1p(_Tp __x) { return __builtin_log1p(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP // DR 568. constexpr float log2(float __x) { return __builtin_log2f(__x); } constexpr long double log2(long double __x) { return __builtin_log2l(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log2(_Tp __x) { return __builtin_log2(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float logb(float __x) { return __builtin_logbf(__x); } constexpr long double logb(long double __x) { return __builtin_logbl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type logb(_Tp __x) { return __builtin_logb(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr long lrint(float __x) { return __builtin_lrintf(__x); } constexpr long lrint(long double __x) { return __builtin_lrintl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, long>::__type lrint(_Tp __x) { return __builtin_lrint(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr long lround(float __x) { return __builtin_lroundf(__x); } constexpr long lround(long double __x) { return __builtin_lroundl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, long>::__type lround(_Tp __x) { return __builtin_lround(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float nearbyint(float __x) { return __builtin_nearbyintf(__x); } constexpr long double nearbyint(long double __x) { return __builtin_nearbyintl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type nearbyint(_Tp __x) { return __builtin_nearbyint(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float nextafter(float __x, float __y) { return __builtin_nextafterf(__x, __y); } constexpr long double nextafter(long double __x, long double __y) { return __builtin_nextafterl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type nextafter(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return nextafter(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float nexttoward(float __x, long double __y) { return __builtin_nexttowardf(__x, __y); } constexpr long double nexttoward(long double __x, long double __y) { return __builtin_nexttowardl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type nexttoward(_Tp __x, long double __y) { return __builtin_nexttoward(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float remainder(float __x, float __y) { return __builtin_remainderf(__x, __y); } constexpr long double remainder(long double __x, long double __y) { return __builtin_remainderl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type remainder(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return remainder(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP inline float remquo(float __x, float __y, int* __pquo) { return __builtin_remquof(__x, __y, __pquo); } inline long double remquo(long double __x, long double __y, int* __pquo) { return __builtin_remquol(__x, __y, __pquo); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type remquo(_Tp __x, _Up __y, int* __pquo) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return remquo(__type(__x), __type(__y), __pquo); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float rint(float __x) { return __builtin_rintf(__x); } constexpr long double rint(long double __x) { return __builtin_rintl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type rint(_Tp __x) { return __builtin_rint(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float round(float __x) { return __builtin_roundf(__x); } constexpr long double round(long double __x) { return __builtin_roundl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type round(_Tp __x) { return __builtin_round(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float scalbln(float __x, long __ex) { return __builtin_scalblnf(__x, __ex); } constexpr long double scalbln(long double __x, long __ex) { return __builtin_scalblnl(__x, __ex); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type scalbln(_Tp __x, long __ex) { return __builtin_scalbln(__x, __ex); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float scalbn(float __x, int __ex) { return __builtin_scalbnf(__x, __ex); } constexpr long double scalbn(long double __x, int __ex) { return __builtin_scalbnl(__x, __ex); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type scalbn(_Tp __x, int __ex) { return __builtin_scalbn(__x, __ex); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float tgamma(float __x) { return __builtin_tgammaf(__x); } constexpr long double tgamma(long double __x) { return __builtin_tgammal(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type tgamma(_Tp __x) { return __builtin_tgamma(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float trunc(float __x) { return __builtin_truncf(__x); } constexpr long double trunc(long double __x) { return __builtin_truncl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type trunc(_Tp __x) { return __builtin_trunc(__x); } #endif #endif // _GLIBCXX_USE_C99_MATH_TR1 #endif // C++11 #if __cplusplus > 201402L // [c.math.hypot3], three-dimensional hypotenuse #define __cpp_lib_hypot 201603 template inline _Tp __hypot3(_Tp __x, _Tp __y, _Tp __z) { __x = std::abs(__x); __y = std::abs(__y); __z = std::abs(__z); if (_Tp __a = __x < __y ? __y < __z ? __z : __y : __x < __z ? __z : __x) return __a * std::sqrt((__x / __a) * (__x / __a) + (__y / __a) * (__y / __a) + (__z / __a) * (__z / __a)); else return {}; } inline float hypot(float __x, float __y, float __z) { return std::__hypot3(__x, __y, __z); } inline double hypot(double __x, double __y, double __z) { return std::__hypot3(__x, __y, __z); } inline long double hypot(long double __x, long double __y, long double __z) { return std::__hypot3(__x, __y, __z); } template typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type hypot(_Tp __x, _Up __y, _Vp __z) { using __type = typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type; return std::__hypot3<__type>(__x, __y, __z); } #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if _GLIBCXX_USE_STD_SPEC_FUNCS # include #endif } // extern "C++" #endif 8/thread000064400000024427152526447520006132 0ustar00// -*- C++ -*- // Copyright (C) 2008-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/thread * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_THREAD #define _GLIBCXX_THREAD 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #include #include #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup threads Threads * @ingroup concurrency * * Classes for thread support. * @{ */ /// thread class thread { public: // Abstract base class for types that wrap arbitrary functors to be // invoked in the new thread of execution. struct _State { virtual ~_State(); virtual void _M_run() = 0; }; using _State_ptr = unique_ptr<_State>; typedef __gthread_t native_handle_type; /// thread::id class id { native_handle_type _M_thread; public: id() noexcept : _M_thread() { } explicit id(native_handle_type __id) : _M_thread(__id) { } private: friend class thread; friend class hash; friend bool operator==(thread::id __x, thread::id __y) noexcept; friend bool operator<(thread::id __x, thread::id __y) noexcept; template friend basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id); }; private: id _M_id; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2097. packaged_task constructors should be constrained template using __not_same = __not_::type>::type, thread>>; public: thread() noexcept = default; template>> explicit thread(_Callable&& __f, _Args&&... __args) { static_assert( __is_invocable::type, typename decay<_Args>::type...>::value, "std::thread arguments must be invocable after conversion to rvalues" ); #ifdef GTHR_ACTIVE_PROXY // Create a reference to pthread_create, not just the gthr weak symbol. auto __depend = reinterpret_cast(&pthread_create); #else auto __depend = nullptr; #endif _M_start_thread(_S_make_state( __make_invoker(std::forward<_Callable>(__f), std::forward<_Args>(__args)...)), __depend); } ~thread() { if (joinable()) std::terminate(); } thread(const thread&) = delete; thread(thread&& __t) noexcept { swap(__t); } thread& operator=(const thread&) = delete; thread& operator=(thread&& __t) noexcept { if (joinable()) std::terminate(); swap(__t); return *this; } void swap(thread& __t) noexcept { std::swap(_M_id, __t._M_id); } bool joinable() const noexcept { return !(_M_id == id()); } void join(); void detach(); thread::id get_id() const noexcept { return _M_id; } /** @pre thread is joinable */ native_handle_type native_handle() { return _M_id._M_thread; } // Returns a value that hints at the number of hardware thread contexts. static unsigned int hardware_concurrency() noexcept; private: template struct _State_impl : public _State { _Callable _M_func; _State_impl(_Callable&& __f) : _M_func(std::forward<_Callable>(__f)) { } void _M_run() { _M_func(); } }; void _M_start_thread(_State_ptr, void (*)()); template static _State_ptr _S_make_state(_Callable&& __f) { using _Impl = _State_impl<_Callable>; return _State_ptr{new _Impl{std::forward<_Callable>(__f)}}; } #if _GLIBCXX_THREAD_ABI_COMPAT public: struct _Impl_base; typedef shared_ptr<_Impl_base> __shared_base_type; struct _Impl_base { __shared_base_type _M_this_ptr; virtual ~_Impl_base() = default; virtual void _M_run() = 0; }; private: void _M_start_thread(__shared_base_type, void (*)()); void _M_start_thread(__shared_base_type); #endif private: // A call wrapper that does INVOKE(forwarded tuple elements...) template struct _Invoker { _Tuple _M_t; template static __tuple_element_t<_Index, _Tuple>&& _S_declval(); template auto _M_invoke(_Index_tuple<_Ind...>) noexcept(noexcept(std::__invoke(_S_declval<_Ind>()...))) -> decltype(std::__invoke(_S_declval<_Ind>()...)) { return std::__invoke(std::get<_Ind>(std::move(_M_t))...); } using _Indices = typename _Build_index_tuple::value>::__type; auto operator()() noexcept(noexcept(std::declval<_Invoker&>()._M_invoke(_Indices()))) -> decltype(std::declval<_Invoker&>()._M_invoke(_Indices())) { return _M_invoke(_Indices()); } }; template using __decayed_tuple = tuple::type...>; public: // Returns a call wrapper that stores // tuple{DECAY_COPY(__callable), DECAY_COPY(__args)...}. template static _Invoker<__decayed_tuple<_Callable, _Args...>> __make_invoker(_Callable&& __callable, _Args&&... __args) { return { __decayed_tuple<_Callable, _Args...>{ std::forward<_Callable>(__callable), std::forward<_Args>(__args)... } }; } }; inline void swap(thread& __x, thread& __y) noexcept { __x.swap(__y); } inline bool operator==(thread::id __x, thread::id __y) noexcept { // pthread_equal is undefined if either thread ID is not valid, so we // can't safely use __gthread_equal on default-constructed values (nor // the non-zero value returned by this_thread::get_id() for // single-threaded programs using GNU libc). Assume EqualityComparable. return __x._M_thread == __y._M_thread; } inline bool operator!=(thread::id __x, thread::id __y) noexcept { return !(__x == __y); } inline bool operator<(thread::id __x, thread::id __y) noexcept { // Pthreads doesn't define any way to do this, so we just have to // assume native_handle_type is LessThanComparable. return __x._M_thread < __y._M_thread; } inline bool operator<=(thread::id __x, thread::id __y) noexcept { return !(__y < __x); } inline bool operator>(thread::id __x, thread::id __y) noexcept { return __y < __x; } inline bool operator>=(thread::id __x, thread::id __y) noexcept { return !(__x < __y); } // DR 889. /// std::hash specialization for thread::id. template<> struct hash : public __hash_base { size_t operator()(const thread::id& __id) const noexcept { return std::_Hash_impl::hash(__id._M_thread); } }; template inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id) { if (__id == thread::id()) return __out << "thread::id of a non-executing thread"; else return __out << __id._M_thread; } /** @namespace std::this_thread * @brief ISO C++ 2011 entities sub-namespace for thread. * 30.3.2 Namespace this_thread. */ namespace this_thread { /// get_id inline thread::id get_id() noexcept { #ifdef __GLIBC__ // For the GNU C library pthread_self() is usable without linking to // libpthread.so but returns 0, so we cannot use it in single-threaded // programs, because this_thread::get_id() != thread::id{} must be true. // We know that pthread_t is an integral type in the GNU C library. if (!__gthread_active_p()) return thread::id(1); #endif return thread::id(__gthread_self()); } /// yield inline void yield() noexcept { #ifdef _GLIBCXX_USE_SCHED_YIELD __gthread_yield(); #endif } void __sleep_for(chrono::seconds, chrono::nanoseconds); /// sleep_for template inline void sleep_for(const chrono::duration<_Rep, _Period>& __rtime) { if (__rtime <= __rtime.zero()) return; auto __s = chrono::duration_cast(__rtime); auto __ns = chrono::duration_cast(__rtime - __s); #ifdef _GLIBCXX_USE_NANOSLEEP __gthread_time_t __ts = { static_cast(__s.count()), static_cast(__ns.count()) }; while (::nanosleep(&__ts, &__ts) == -1 && errno == EINTR) { } #else __sleep_for(__s, __ns); #endif } /// sleep_until template inline void sleep_until(const chrono::time_point<_Clock, _Duration>& __atime) { auto __now = _Clock::now(); if (_Clock::is_steady) { if (__now < __atime) sleep_for(__atime - __now); return; } while (__now < __atime) { sleep_for(__atime - __now); __now = _Clock::now(); } } } // @} group threads _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif // _GLIBCXX_THREAD 8/typeindex000064400000006025152526447520006666 0ustar00// C++11 -*- C++ -*- // Copyright (C) 2010-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/typeindex * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_TYPEINDEX #define _GLIBCXX_TYPEINDEX 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Class type_index * @ingroup utilities * * The class type_index provides a simple wrapper for type_info * which can be used as an index type in associative containers * (23.6) and in unordered associative containers (23.7). */ struct type_index { type_index(const type_info& __rhs) noexcept : _M_target(&__rhs) { } bool operator==(const type_index& __rhs) const noexcept { return *_M_target == *__rhs._M_target; } bool operator!=(const type_index& __rhs) const noexcept { return *_M_target != *__rhs._M_target; } bool operator<(const type_index& __rhs) const noexcept { return _M_target->before(*__rhs._M_target); } bool operator<=(const type_index& __rhs) const noexcept { return !__rhs._M_target->before(*_M_target); } bool operator>(const type_index& __rhs) const noexcept { return __rhs._M_target->before(*_M_target); } bool operator>=(const type_index& __rhs) const noexcept { return !_M_target->before(*__rhs._M_target); } size_t hash_code() const noexcept { return _M_target->hash_code(); } const char* name() const noexcept { return _M_target->name(); } private: const type_info* _M_target; }; template struct hash; /// std::hash specialization for type_index. template<> struct hash { typedef size_t result_type; typedef type_index argument_type; size_t operator()(const type_index& __ti) const noexcept { return __ti.hash_code(); } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_TYPEINDEX 8/cstdint000064400000004167152526447520006332 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/cstdint * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_CSTDINT #define _GLIBCXX_CSTDINT 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #if _GLIBCXX_HAVE_STDINT_H # include #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std { using ::int8_t; using ::int16_t; using ::int32_t; using ::int64_t; using ::int_fast8_t; using ::int_fast16_t; using ::int_fast32_t; using ::int_fast64_t; using ::int_least8_t; using ::int_least16_t; using ::int_least32_t; using ::int_least64_t; using ::intmax_t; using ::intptr_t; using ::uint8_t; using ::uint16_t; using ::uint32_t; using ::uint64_t; using ::uint_fast8_t; using ::uint_fast16_t; using ::uint_fast32_t; using ::uint_fast64_t; using ::uint_least8_t; using ::uint_least16_t; using ::uint_least32_t; using ::uint_least64_t; using ::uintmax_t; using ::uintptr_t; } // namespace std #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif // _GLIBCXX_CSTDINT 8/cstdbool000064400000002571152526447520006470 0ustar00// -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/cstdbool * This is a Standard C++ Library header. */ #pragma GCC system_header #ifndef _GLIBCXX_CSTDBOOL #define _GLIBCXX_CSTDBOOL 1 #if __cplusplus < 201103L # include #else # include # if _GLIBCXX_HAVE_STDBOOL_H # include # endif #endif #endif 8/ciso646000064400000002670152526447520006054 0ustar00// -*- C++ -*- forwarding header. // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ciso646 * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c iso646.h, * which is empty in C++. */ #ifndef _GLIBCXX_CISO646 #define _GLIBCXX_CISO646 #pragma GCC system_header #include #endif 8/atomic000064400000120141152526447520006125 0ustar00// -*- C++ -*- header. // Copyright (C) 2008-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/atomic * This is a Standard C++ Library header. */ // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl. // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html #ifndef _GLIBCXX_ATOMIC #define _GLIBCXX_ATOMIC 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup atomics * @{ */ #if __cplusplus > 201402L # define __cpp_lib_atomic_is_always_lock_free 201603 #endif template struct atomic; /// atomic // NB: No operators or fetch-operations for this type. template<> struct atomic { private: __atomic_base _M_base; public: atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(bool __i) noexcept : _M_base(__i) { } bool operator=(bool __i) noexcept { return _M_base.operator=(__i); } bool operator=(bool __i) volatile noexcept { return _M_base.operator=(__i); } operator bool() const noexcept { return _M_base.load(); } operator bool() const volatile noexcept { return _M_base.load(); } bool is_lock_free() const noexcept { return _M_base.is_lock_free(); } bool is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); } #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2; #endif void store(bool __i, memory_order __m = memory_order_seq_cst) noexcept { _M_base.store(__i, __m); } void store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept { _M_base.store(__i, __m); } bool load(memory_order __m = memory_order_seq_cst) const noexcept { return _M_base.load(__m); } bool load(memory_order __m = memory_order_seq_cst) const volatile noexcept { return _M_base.load(__m); } bool exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept { return _M_base.exchange(__i, __m); } bool exchange(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_base.exchange(__i, __m); } bool compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, memory_order __m2) noexcept { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } bool compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, memory_order __m2) volatile noexcept { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } bool compare_exchange_weak(bool& __i1, bool __i2, memory_order __m = memory_order_seq_cst) noexcept { return _M_base.compare_exchange_weak(__i1, __i2, __m); } bool compare_exchange_weak(bool& __i1, bool __i2, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_base.compare_exchange_weak(__i1, __i2, __m); } bool compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, memory_order __m2) noexcept { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } bool compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, memory_order __m2) volatile noexcept { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } bool compare_exchange_strong(bool& __i1, bool __i2, memory_order __m = memory_order_seq_cst) noexcept { return _M_base.compare_exchange_strong(__i1, __i2, __m); } bool compare_exchange_strong(bool& __i1, bool __i2, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_base.compare_exchange_strong(__i1, __i2, __m); } }; /** * @brief Generic atomic type, primary class template. * * @tparam _Tp Type to be made atomic, must be trivally copyable. */ template struct atomic { private: // Align 1/2/4/8/16-byte types to at least their size. static constexpr int _S_min_alignment = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16 ? 0 : sizeof(_Tp); static constexpr int _S_alignment = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp); alignas(_S_alignment) _Tp _M_i; static_assert(__is_trivially_copyable(_Tp), "std::atomic requires a trivially copyable type"); static_assert(sizeof(_Tp) > 0, "Incomplete or zero-sized types are not supported"); public: atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(_Tp __i) noexcept : _M_i(__i) { } operator _Tp() const noexcept { return load(); } operator _Tp() const volatile noexcept { return load(); } _Tp operator=(_Tp __i) noexcept { store(__i); return __i; } _Tp operator=(_Tp __i) volatile noexcept { store(__i); return __i; } bool is_lock_free() const noexcept { // Produce a fake, minimally aligned pointer. return __atomic_is_lock_free(sizeof(_M_i), reinterpret_cast(-__alignof(_M_i))); } bool is_lock_free() const volatile noexcept { // Produce a fake, minimally aligned pointer. return __atomic_is_lock_free(sizeof(_M_i), reinterpret_cast(-__alignof(_M_i))); } #if __cplusplus > 201402L static constexpr bool is_always_lock_free = __atomic_always_lock_free(sizeof(_M_i), 0); #endif void store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), __m); } void store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), __m); } _Tp load(memory_order __m = memory_order_seq_cst) const noexcept { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); __atomic_load(std::__addressof(_M_i), __ptr, __m); return *__ptr; } _Tp load(memory_order __m = memory_order_seq_cst) const volatile noexcept { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); __atomic_load(std::__addressof(_M_i), __ptr, __m); return *__ptr; } _Tp exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i), __ptr, __m); return *__ptr; } _Tp exchange(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i), __ptr, __m); return *__ptr; } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) noexcept { return __atomic_compare_exchange(std::__addressof(_M_i), std::__addressof(__e), std::__addressof(__i), true, __s, __f); } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) volatile noexcept { return __atomic_compare_exchange(std::__addressof(_M_i), std::__addressof(__e), std::__addressof(__i), true, __s, __f); } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __m = memory_order_seq_cst) noexcept { return compare_exchange_weak(__e, __i, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return compare_exchange_weak(__e, __i, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) noexcept { return __atomic_compare_exchange(std::__addressof(_M_i), std::__addressof(__e), std::__addressof(__i), false, __s, __f); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) volatile noexcept { return __atomic_compare_exchange(std::__addressof(_M_i), std::__addressof(__e), std::__addressof(__i), false, __s, __f); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __m = memory_order_seq_cst) noexcept { return compare_exchange_strong(__e, __i, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return compare_exchange_strong(__e, __i, __m, __cmpexch_failure_order(__m)); } }; /// Partial specialization for pointer types. template struct atomic<_Tp*> { typedef _Tp* __pointer_type; typedef __atomic_base<_Tp*> __base_type; __base_type _M_b; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { } operator __pointer_type() const noexcept { return __pointer_type(_M_b); } operator __pointer_type() const volatile noexcept { return __pointer_type(_M_b); } __pointer_type operator=(__pointer_type __p) noexcept { return _M_b.operator=(__p); } __pointer_type operator=(__pointer_type __p) volatile noexcept { return _M_b.operator=(__p); } __pointer_type operator++(int) noexcept { return _M_b++; } __pointer_type operator++(int) volatile noexcept { return _M_b++; } __pointer_type operator--(int) noexcept { return _M_b--; } __pointer_type operator--(int) volatile noexcept { return _M_b--; } __pointer_type operator++() noexcept { return ++_M_b; } __pointer_type operator++() volatile noexcept { return ++_M_b; } __pointer_type operator--() noexcept { return --_M_b; } __pointer_type operator--() volatile noexcept { return --_M_b; } __pointer_type operator+=(ptrdiff_t __d) noexcept { return _M_b.operator+=(__d); } __pointer_type operator+=(ptrdiff_t __d) volatile noexcept { return _M_b.operator+=(__d); } __pointer_type operator-=(ptrdiff_t __d) noexcept { return _M_b.operator-=(__d); } __pointer_type operator-=(ptrdiff_t __d) volatile noexcept { return _M_b.operator-=(__d); } bool is_lock_free() const noexcept { return _M_b.is_lock_free(); } bool is_lock_free() const volatile noexcept { return _M_b.is_lock_free(); } #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_POINTER_LOCK_FREE == 2; #endif void store(__pointer_type __p, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.store(__p, __m); } void store(__pointer_type __p, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.store(__p, __m); } __pointer_type load(memory_order __m = memory_order_seq_cst) const noexcept { return _M_b.load(__m); } __pointer_type load(memory_order __m = memory_order_seq_cst) const volatile noexcept { return _M_b.load(__m); } __pointer_type exchange(__pointer_type __p, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.exchange(__p, __m); } __pointer_type exchange(__pointer_type __p, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.exchange(__p, __m); } bool compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } bool compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) volatile noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } bool compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, memory_order __m = memory_order_seq_cst) noexcept { return compare_exchange_weak(__p1, __p2, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, memory_order __m = memory_order_seq_cst) volatile noexcept { return compare_exchange_weak(__p1, __p2, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) volatile noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m, __cmpexch_failure_order(__m)); } __pointer_type fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.fetch_add(__d, __m); } __pointer_type fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.fetch_add(__d, __m); } __pointer_type fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.fetch_sub(__d, __m); } __pointer_type fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.fetch_sub(__d, __m); } }; /// Explicit specialization for char. template<> struct atomic : __atomic_base { typedef char __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2; #endif }; /// Explicit specialization for signed char. template<> struct atomic : __atomic_base { typedef signed char __integral_type; typedef __atomic_base __base_type; atomic() noexcept= default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned char. template<> struct atomic : __atomic_base { typedef unsigned char __integral_type; typedef __atomic_base __base_type; atomic() noexcept= default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2; #endif }; /// Explicit specialization for short. template<> struct atomic : __atomic_base { typedef short __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned short. template<> struct atomic : __atomic_base { typedef unsigned short __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2; #endif }; /// Explicit specialization for int. template<> struct atomic : __atomic_base { typedef int __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned int. template<> struct atomic : __atomic_base { typedef unsigned int __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2; #endif }; /// Explicit specialization for long. template<> struct atomic : __atomic_base { typedef long __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned long. template<> struct atomic : __atomic_base { typedef unsigned long __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2; #endif }; /// Explicit specialization for long long. template<> struct atomic : __atomic_base { typedef long long __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned long long. template<> struct atomic : __atomic_base { typedef unsigned long long __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2; #endif }; /// Explicit specialization for wchar_t. template<> struct atomic : __atomic_base { typedef wchar_t __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_WCHAR_T_LOCK_FREE == 2; #endif }; /// Explicit specialization for char16_t. template<> struct atomic : __atomic_base { typedef char16_t __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR16_T_LOCK_FREE == 2; #endif }; /// Explicit specialization for char32_t. template<> struct atomic : __atomic_base { typedef char32_t __integral_type; typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR32_T_LOCK_FREE == 2; #endif }; /// atomic_bool typedef atomic atomic_bool; /// atomic_char typedef atomic atomic_char; /// atomic_schar typedef atomic atomic_schar; /// atomic_uchar typedef atomic atomic_uchar; /// atomic_short typedef atomic atomic_short; /// atomic_ushort typedef atomic atomic_ushort; /// atomic_int typedef atomic atomic_int; /// atomic_uint typedef atomic atomic_uint; /// atomic_long typedef atomic atomic_long; /// atomic_ulong typedef atomic atomic_ulong; /// atomic_llong typedef atomic atomic_llong; /// atomic_ullong typedef atomic atomic_ullong; /// atomic_wchar_t typedef atomic atomic_wchar_t; /// atomic_char16_t typedef atomic atomic_char16_t; /// atomic_char32_t typedef atomic atomic_char32_t; #ifdef _GLIBCXX_USE_C99_STDINT_TR1 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2441. Exact-width atomic typedefs should be provided /// atomic_int8_t typedef atomic atomic_int8_t; /// atomic_uint8_t typedef atomic atomic_uint8_t; /// atomic_int16_t typedef atomic atomic_int16_t; /// atomic_uint16_t typedef atomic atomic_uint16_t; /// atomic_int32_t typedef atomic atomic_int32_t; /// atomic_uint32_t typedef atomic atomic_uint32_t; /// atomic_int64_t typedef atomic atomic_int64_t; /// atomic_uint64_t typedef atomic atomic_uint64_t; /// atomic_int_least8_t typedef atomic atomic_int_least8_t; /// atomic_uint_least8_t typedef atomic atomic_uint_least8_t; /// atomic_int_least16_t typedef atomic atomic_int_least16_t; /// atomic_uint_least16_t typedef atomic atomic_uint_least16_t; /// atomic_int_least32_t typedef atomic atomic_int_least32_t; /// atomic_uint_least32_t typedef atomic atomic_uint_least32_t; /// atomic_int_least64_t typedef atomic atomic_int_least64_t; /// atomic_uint_least64_t typedef atomic atomic_uint_least64_t; /// atomic_int_fast8_t typedef atomic atomic_int_fast8_t; /// atomic_uint_fast8_t typedef atomic atomic_uint_fast8_t; /// atomic_int_fast16_t typedef atomic atomic_int_fast16_t; /// atomic_uint_fast16_t typedef atomic atomic_uint_fast16_t; /// atomic_int_fast32_t typedef atomic atomic_int_fast32_t; /// atomic_uint_fast32_t typedef atomic atomic_uint_fast32_t; /// atomic_int_fast64_t typedef atomic atomic_int_fast64_t; /// atomic_uint_fast64_t typedef atomic atomic_uint_fast64_t; #endif /// atomic_intptr_t typedef atomic atomic_intptr_t; /// atomic_uintptr_t typedef atomic atomic_uintptr_t; /// atomic_size_t typedef atomic atomic_size_t; /// atomic_ptrdiff_t typedef atomic atomic_ptrdiff_t; #ifdef _GLIBCXX_USE_C99_STDINT_TR1 /// atomic_intmax_t typedef atomic atomic_intmax_t; /// atomic_uintmax_t typedef atomic atomic_uintmax_t; #endif // Function definitions, atomic_flag operations. inline bool atomic_flag_test_and_set_explicit(atomic_flag* __a, memory_order __m) noexcept { return __a->test_and_set(__m); } inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, memory_order __m) noexcept { return __a->test_and_set(__m); } inline void atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept { __a->clear(__m); } inline void atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __m) noexcept { __a->clear(__m); } inline bool atomic_flag_test_and_set(atomic_flag* __a) noexcept { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } inline bool atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } inline void atomic_flag_clear(atomic_flag* __a) noexcept { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } inline void atomic_flag_clear(volatile atomic_flag* __a) noexcept { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } // Function templates generally applicable to atomic types. template inline bool atomic_is_lock_free(const atomic<_ITp>* __a) noexcept { return __a->is_lock_free(); } template inline bool atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept { return __a->is_lock_free(); } template inline void atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept { __a->store(__i, memory_order_relaxed); } template inline void atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept { __a->store(__i, memory_order_relaxed); } template inline void atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, memory_order __m) noexcept { __a->store(__i, __m); } template inline void atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i, memory_order __m) noexcept { __a->store(__i, __m); } template inline _ITp atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept { return __a->load(__m); } template inline _ITp atomic_load_explicit(const volatile atomic<_ITp>* __a, memory_order __m) noexcept { return __a->load(__m); } template inline _ITp atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->exchange(__i, __m); } template inline _ITp atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->exchange(__i, __m); } template inline bool atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, _ITp* __i1, _ITp __i2, memory_order __m1, memory_order __m2) noexcept { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } template inline bool atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, _ITp* __i1, _ITp __i2, memory_order __m1, memory_order __m2) noexcept { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } template inline bool atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, _ITp* __i1, _ITp __i2, memory_order __m1, memory_order __m2) noexcept { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } template inline bool atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, _ITp* __i1, _ITp __i2, memory_order __m1, memory_order __m2) noexcept { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } template inline void atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept { atomic_store_explicit(__a, __i, memory_order_seq_cst); } template inline void atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept { atomic_store_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_load(const atomic<_ITp>* __a) noexcept { return atomic_load_explicit(__a, memory_order_seq_cst); } template inline _ITp atomic_load(const volatile atomic<_ITp>* __a) noexcept { return atomic_load_explicit(__a, memory_order_seq_cst); } template inline _ITp atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } template inline bool atomic_compare_exchange_weak(atomic<_ITp>* __a, _ITp* __i1, _ITp __i2) noexcept { return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, memory_order_seq_cst, memory_order_seq_cst); } template inline bool atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, _ITp* __i1, _ITp __i2) noexcept { return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, memory_order_seq_cst, memory_order_seq_cst); } template inline bool atomic_compare_exchange_strong(atomic<_ITp>* __a, _ITp* __i1, _ITp __i2) noexcept { return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, memory_order_seq_cst, memory_order_seq_cst); } template inline bool atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, _ITp* __i1, _ITp __i2) noexcept { return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, memory_order_seq_cst, memory_order_seq_cst); } // Function templates for atomic_integral operations only, using // __atomic_base. Template argument should be constricted to // intergral types as specified in the standard, excluding address // types. template inline _ITp atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_add(__i, __m); } template inline _ITp atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_add(__i, __m); } template inline _ITp atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_sub(__i, __m); } template inline _ITp atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_sub(__i, __m); } template inline _ITp atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_and(__i, __m); } template inline _ITp atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_and(__i, __m); } template inline _ITp atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_or(__i, __m); } template inline _ITp atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_or(__i, __m); } template inline _ITp atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_xor(__i, __m); } template inline _ITp atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_xor(__i, __m); } template inline _ITp atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } template inline _ITp atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } // Partial specializations for pointers. template inline _ITp* atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, memory_order __m) noexcept { return __a->fetch_add(__d, __m); } template inline _ITp* atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, memory_order __m) noexcept { return __a->fetch_add(__d, __m); } template inline _ITp* atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept { return __a->fetch_add(__d); } template inline _ITp* atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept { return __a->fetch_add(__d); } template inline _ITp* atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, memory_order __m) noexcept { return __a->fetch_sub(__d, __m); } template inline _ITp* atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, memory_order __m) noexcept { return __a->fetch_sub(__d, __m); } template inline _ITp* atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept { return __a->fetch_sub(__d); } template inline _ITp* atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept { return __a->fetch_sub(__d); } // @} group atomics _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #endif // _GLIBCXX_ATOMIC 8/cstdlib000064400000014265152526447520006306 0ustar00// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/cstdlib * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c stdlib.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 20.4.6 C library // #pragma GCC system_header #include #ifndef _GLIBCXX_CSTDLIB #define _GLIBCXX_CSTDLIB 1 #if !_GLIBCXX_HOSTED // The C standard does not require a freestanding implementation to // provide . However, the C++ standard does still require // -- but only the functionality mentioned in // [lib.support.start.term]. #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 namespace std { extern "C" void abort(void) throw () _GLIBCXX_NORETURN; extern "C" int atexit(void (*)(void)) throw (); extern "C" void exit(int) throw () _GLIBCXX_NORETURN; #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT extern "C" int at_quick_exit(void (*)(void)) throw (); # endif # ifdef _GLIBCXX_HAVE_QUICK_EXIT extern "C" void quick_exit(int) throw() _GLIBCXX_NORETURN; # endif #endif } // namespace std #else // Need to ensure this finds the C library's not a libstdc++ // wrapper that might already be installed later in the include search path. #define _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include_next #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include // Get rid of those macros defined in in lieu of real functions. #undef abort #if __cplusplus >= 201703L && defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) # undef aligned_alloc #endif #undef atexit #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT # undef at_quick_exit # endif #endif #undef atof #undef atoi #undef atol #undef bsearch #undef calloc #undef div #undef exit #undef free #undef getenv #undef labs #undef ldiv #undef malloc #undef mblen #undef mbstowcs #undef mbtowc #undef qsort #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_QUICK_EXIT # undef quick_exit # endif #endif #undef rand #undef realloc #undef srand #undef strtod #undef strtol #undef strtoul #undef system #undef wcstombs #undef wctomb extern "C++" { namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::div_t; using ::ldiv_t; using ::abort; #if __cplusplus >= 201703L && defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) using ::aligned_alloc; #endif using ::atexit; #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT using ::at_quick_exit; # endif #endif using ::atof; using ::atoi; using ::atol; using ::bsearch; using ::calloc; using ::div; using ::exit; using ::free; using ::getenv; using ::labs; using ::ldiv; using ::malloc; #ifdef _GLIBCXX_HAVE_MBSTATE_T using ::mblen; using ::mbstowcs; using ::mbtowc; #endif // _GLIBCXX_HAVE_MBSTATE_T using ::qsort; #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_QUICK_EXIT using ::quick_exit; # endif #endif using ::rand; using ::realloc; using ::srand; using ::strtod; using ::strtol; using ::strtoul; using ::system; #ifdef _GLIBCXX_USE_WCHAR_T using ::wcstombs; using ::wctomb; #endif // _GLIBCXX_USE_WCHAR_T #ifndef __CORRECT_ISO_CPP_STDLIB_H_PROTO inline ldiv_t div(long __i, long __j) { return ldiv(__i, __j); } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if _GLIBCXX_USE_C99_STDLIB #undef _Exit #undef llabs #undef lldiv #undef atoll #undef strtoll #undef strtoull #undef strtof #undef strtold namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::lldiv_t; #endif #if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC extern "C" void (_Exit)(int) throw () _GLIBCXX_NORETURN; #endif #if !_GLIBCXX_USE_C99_DYNAMIC using ::_Exit; #endif #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::llabs; inline lldiv_t div(long long __n, long long __d) { lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; } using ::lldiv; #endif #if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC extern "C" long long int (atoll)(const char *) throw (); extern "C" long long int (strtoll)(const char * __restrict, char ** __restrict, int) throw (); extern "C" unsigned long long int (strtoull)(const char * __restrict, char ** __restrict, int) throw (); #endif #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::atoll; using ::strtoll; using ::strtoull; #endif using ::strtof; using ::strtold; _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx namespace std { #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::__gnu_cxx::lldiv_t; #endif using ::__gnu_cxx::_Exit; #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::__gnu_cxx::llabs; using ::__gnu_cxx::div; using ::__gnu_cxx::lldiv; #endif using ::__gnu_cxx::atoll; using ::__gnu_cxx::strtof; using ::__gnu_cxx::strtoll; using ::__gnu_cxx::strtoull; using ::__gnu_cxx::strtold; } // namespace std #endif // _GLIBCXX_USE_C99_STDLIB } // extern "C++" #endif // !_GLIBCXX_HOSTED #endif 8/bitset000064400000131526152526447520006154 0ustar00// -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * Copyright (c) 1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file include/bitset * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_BITSET #define _GLIBCXX_BITSET 1 #pragma GCC system_header #include #include // For invalid_argument, out_of_range, // overflow_error #include #include #if __cplusplus >= 201103L # include #endif #define _GLIBCXX_BITSET_BITS_PER_WORD (__CHAR_BIT__ * __SIZEOF_LONG__) #define _GLIBCXX_BITSET_WORDS(__n) \ ((__n) / _GLIBCXX_BITSET_BITS_PER_WORD + \ ((__n) % _GLIBCXX_BITSET_BITS_PER_WORD == 0 ? 0 : 1)) #define _GLIBCXX_BITSET_BITS_PER_ULL (__CHAR_BIT__ * __SIZEOF_LONG_LONG__) namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /** * Base class, general case. It is a class invariant that _Nw will be * nonnegative. * * See documentation for bitset. */ template struct _Base_bitset { typedef unsigned long _WordT; /// 0 is the least significant word. _WordT _M_w[_Nw]; _GLIBCXX_CONSTEXPR _Base_bitset() _GLIBCXX_NOEXCEPT : _M_w() { } #if __cplusplus >= 201103L constexpr _Base_bitset(unsigned long long __val) noexcept : _M_w{ _WordT(__val) #if __SIZEOF_LONG_LONG__ > __SIZEOF_LONG__ , _WordT(__val >> _GLIBCXX_BITSET_BITS_PER_WORD) #endif } { } #else _Base_bitset(unsigned long __val) : _M_w() { _M_w[0] = __val; } #endif static _GLIBCXX_CONSTEXPR size_t _S_whichword(size_t __pos) _GLIBCXX_NOEXCEPT { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } static _GLIBCXX_CONSTEXPR size_t _S_whichbyte(size_t __pos) _GLIBCXX_NOEXCEPT { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } static _GLIBCXX_CONSTEXPR size_t _S_whichbit(size_t __pos) _GLIBCXX_NOEXCEPT { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } static _GLIBCXX_CONSTEXPR _WordT _S_maskbit(size_t __pos) _GLIBCXX_NOEXCEPT { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } _WordT& _M_getword(size_t __pos) _GLIBCXX_NOEXCEPT { return _M_w[_S_whichword(__pos)]; } _GLIBCXX_CONSTEXPR _WordT _M_getword(size_t __pos) const _GLIBCXX_NOEXCEPT { return _M_w[_S_whichword(__pos)]; } #if __cplusplus >= 201103L const _WordT* _M_getdata() const noexcept { return _M_w; } #endif _WordT& _M_hiword() _GLIBCXX_NOEXCEPT { return _M_w[_Nw - 1]; } _GLIBCXX_CONSTEXPR _WordT _M_hiword() const _GLIBCXX_NOEXCEPT { return _M_w[_Nw - 1]; } void _M_do_and(const _Base_bitset<_Nw>& __x) _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) _M_w[__i] &= __x._M_w[__i]; } void _M_do_or(const _Base_bitset<_Nw>& __x) _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) _M_w[__i] |= __x._M_w[__i]; } void _M_do_xor(const _Base_bitset<_Nw>& __x) _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) _M_w[__i] ^= __x._M_w[__i]; } void _M_do_left_shift(size_t __shift) _GLIBCXX_NOEXCEPT; void _M_do_right_shift(size_t __shift) _GLIBCXX_NOEXCEPT; void _M_do_flip() _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) _M_w[__i] = ~_M_w[__i]; } void _M_do_set() _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) _M_w[__i] = ~static_cast<_WordT>(0); } void _M_do_reset() _GLIBCXX_NOEXCEPT { __builtin_memset(_M_w, 0, _Nw * sizeof(_WordT)); } bool _M_is_equal(const _Base_bitset<_Nw>& __x) const _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; ++__i) if (_M_w[__i] != __x._M_w[__i]) return false; return true; } template bool _M_are_all() const _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw - 1; __i++) if (_M_w[__i] != ~static_cast<_WordT>(0)) return false; return _M_hiword() == (~static_cast<_WordT>(0) >> (_Nw * _GLIBCXX_BITSET_BITS_PER_WORD - _Nb)); } bool _M_is_any() const _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) if (_M_w[__i] != static_cast<_WordT>(0)) return true; return false; } size_t _M_do_count() const _GLIBCXX_NOEXCEPT { size_t __result = 0; for (size_t __i = 0; __i < _Nw; __i++) __result += __builtin_popcountl(_M_w[__i]); return __result; } unsigned long _M_do_to_ulong() const; #if __cplusplus >= 201103L unsigned long long _M_do_to_ullong() const; #endif // find first "on" bit size_t _M_do_find_first(size_t) const _GLIBCXX_NOEXCEPT; // find the next "on" bit that follows "prev" size_t _M_do_find_next(size_t, size_t) const _GLIBCXX_NOEXCEPT; }; // Definitions of non-inline functions from _Base_bitset. template void _Base_bitset<_Nw>::_M_do_left_shift(size_t __shift) _GLIBCXX_NOEXCEPT { if (__builtin_expect(__shift != 0, 1)) { const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; if (__offset == 0) for (size_t __n = _Nw - 1; __n >= __wshift; --__n) _M_w[__n] = _M_w[__n - __wshift]; else { const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD - __offset); for (size_t __n = _Nw - 1; __n > __wshift; --__n) _M_w[__n] = ((_M_w[__n - __wshift] << __offset) | (_M_w[__n - __wshift - 1] >> __sub_offset)); _M_w[__wshift] = _M_w[0] << __offset; } std::fill(_M_w + 0, _M_w + __wshift, static_cast<_WordT>(0)); } } template void _Base_bitset<_Nw>::_M_do_right_shift(size_t __shift) _GLIBCXX_NOEXCEPT { if (__builtin_expect(__shift != 0, 1)) { const size_t __wshift = __shift / _GLIBCXX_BITSET_BITS_PER_WORD; const size_t __offset = __shift % _GLIBCXX_BITSET_BITS_PER_WORD; const size_t __limit = _Nw - __wshift - 1; if (__offset == 0) for (size_t __n = 0; __n <= __limit; ++__n) _M_w[__n] = _M_w[__n + __wshift]; else { const size_t __sub_offset = (_GLIBCXX_BITSET_BITS_PER_WORD - __offset); for (size_t __n = 0; __n < __limit; ++__n) _M_w[__n] = ((_M_w[__n + __wshift] >> __offset) | (_M_w[__n + __wshift + 1] << __sub_offset)); _M_w[__limit] = _M_w[_Nw-1] >> __offset; } std::fill(_M_w + __limit + 1, _M_w + _Nw, static_cast<_WordT>(0)); } } template unsigned long _Base_bitset<_Nw>::_M_do_to_ulong() const { for (size_t __i = 1; __i < _Nw; ++__i) if (_M_w[__i]) __throw_overflow_error(__N("_Base_bitset::_M_do_to_ulong")); return _M_w[0]; } #if __cplusplus >= 201103L template unsigned long long _Base_bitset<_Nw>::_M_do_to_ullong() const { const bool __dw = sizeof(unsigned long long) > sizeof(unsigned long); for (size_t __i = 1 + __dw; __i < _Nw; ++__i) if (_M_w[__i]) __throw_overflow_error(__N("_Base_bitset::_M_do_to_ullong")); if (__dw) return _M_w[0] + (static_cast(_M_w[1]) << _GLIBCXX_BITSET_BITS_PER_WORD); return _M_w[0]; } #endif template size_t _Base_bitset<_Nw>:: _M_do_find_first(size_t __not_found) const _GLIBCXX_NOEXCEPT { for (size_t __i = 0; __i < _Nw; __i++) { _WordT __thisword = _M_w[__i]; if (__thisword != static_cast<_WordT>(0)) return (__i * _GLIBCXX_BITSET_BITS_PER_WORD + __builtin_ctzl(__thisword)); } // not found, so return an indication of failure. return __not_found; } template size_t _Base_bitset<_Nw>:: _M_do_find_next(size_t __prev, size_t __not_found) const _GLIBCXX_NOEXCEPT { // make bound inclusive ++__prev; // check out of bounds if (__prev >= _Nw * _GLIBCXX_BITSET_BITS_PER_WORD) return __not_found; // search first word size_t __i = _S_whichword(__prev); _WordT __thisword = _M_w[__i]; // mask off bits below bound __thisword &= (~static_cast<_WordT>(0)) << _S_whichbit(__prev); if (__thisword != static_cast<_WordT>(0)) return (__i * _GLIBCXX_BITSET_BITS_PER_WORD + __builtin_ctzl(__thisword)); // check subsequent words __i++; for (; __i < _Nw; __i++) { __thisword = _M_w[__i]; if (__thisword != static_cast<_WordT>(0)) return (__i * _GLIBCXX_BITSET_BITS_PER_WORD + __builtin_ctzl(__thisword)); } // not found, so return an indication of failure. return __not_found; } // end _M_do_find_next /** * Base class, specialization for a single word. * * See documentation for bitset. */ template<> struct _Base_bitset<1> { typedef unsigned long _WordT; _WordT _M_w; _GLIBCXX_CONSTEXPR _Base_bitset() _GLIBCXX_NOEXCEPT : _M_w(0) { } #if __cplusplus >= 201103L constexpr _Base_bitset(unsigned long long __val) noexcept #else _Base_bitset(unsigned long __val) #endif : _M_w(__val) { } static _GLIBCXX_CONSTEXPR size_t _S_whichword(size_t __pos) _GLIBCXX_NOEXCEPT { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } static _GLIBCXX_CONSTEXPR size_t _S_whichbyte(size_t __pos) _GLIBCXX_NOEXCEPT { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } static _GLIBCXX_CONSTEXPR size_t _S_whichbit(size_t __pos) _GLIBCXX_NOEXCEPT { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } static _GLIBCXX_CONSTEXPR _WordT _S_maskbit(size_t __pos) _GLIBCXX_NOEXCEPT { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } _WordT& _M_getword(size_t) _GLIBCXX_NOEXCEPT { return _M_w; } _GLIBCXX_CONSTEXPR _WordT _M_getword(size_t) const _GLIBCXX_NOEXCEPT { return _M_w; } #if __cplusplus >= 201103L const _WordT* _M_getdata() const noexcept { return &_M_w; } #endif _WordT& _M_hiword() _GLIBCXX_NOEXCEPT { return _M_w; } _GLIBCXX_CONSTEXPR _WordT _M_hiword() const _GLIBCXX_NOEXCEPT { return _M_w; } void _M_do_and(const _Base_bitset<1>& __x) _GLIBCXX_NOEXCEPT { _M_w &= __x._M_w; } void _M_do_or(const _Base_bitset<1>& __x) _GLIBCXX_NOEXCEPT { _M_w |= __x._M_w; } void _M_do_xor(const _Base_bitset<1>& __x) _GLIBCXX_NOEXCEPT { _M_w ^= __x._M_w; } void _M_do_left_shift(size_t __shift) _GLIBCXX_NOEXCEPT { _M_w <<= __shift; } void _M_do_right_shift(size_t __shift) _GLIBCXX_NOEXCEPT { _M_w >>= __shift; } void _M_do_flip() _GLIBCXX_NOEXCEPT { _M_w = ~_M_w; } void _M_do_set() _GLIBCXX_NOEXCEPT { _M_w = ~static_cast<_WordT>(0); } void _M_do_reset() _GLIBCXX_NOEXCEPT { _M_w = 0; } bool _M_is_equal(const _Base_bitset<1>& __x) const _GLIBCXX_NOEXCEPT { return _M_w == __x._M_w; } template bool _M_are_all() const _GLIBCXX_NOEXCEPT { return _M_w == (~static_cast<_WordT>(0) >> (_GLIBCXX_BITSET_BITS_PER_WORD - _Nb)); } bool _M_is_any() const _GLIBCXX_NOEXCEPT { return _M_w != 0; } size_t _M_do_count() const _GLIBCXX_NOEXCEPT { return __builtin_popcountl(_M_w); } unsigned long _M_do_to_ulong() const _GLIBCXX_NOEXCEPT { return _M_w; } #if __cplusplus >= 201103L unsigned long long _M_do_to_ullong() const noexcept { return _M_w; } #endif size_t _M_do_find_first(size_t __not_found) const _GLIBCXX_NOEXCEPT { if (_M_w != 0) return __builtin_ctzl(_M_w); else return __not_found; } // find the next "on" bit that follows "prev" size_t _M_do_find_next(size_t __prev, size_t __not_found) const _GLIBCXX_NOEXCEPT { ++__prev; if (__prev >= ((size_t) _GLIBCXX_BITSET_BITS_PER_WORD)) return __not_found; _WordT __x = _M_w >> __prev; if (__x != 0) return __builtin_ctzl(__x) + __prev; else return __not_found; } }; /** * Base class, specialization for no storage (zero-length %bitset). * * See documentation for bitset. */ template<> struct _Base_bitset<0> { typedef unsigned long _WordT; _GLIBCXX_CONSTEXPR _Base_bitset() _GLIBCXX_NOEXCEPT { } #if __cplusplus >= 201103L constexpr _Base_bitset(unsigned long long) noexcept #else _Base_bitset(unsigned long) #endif { } static _GLIBCXX_CONSTEXPR size_t _S_whichword(size_t __pos) _GLIBCXX_NOEXCEPT { return __pos / _GLIBCXX_BITSET_BITS_PER_WORD; } static _GLIBCXX_CONSTEXPR size_t _S_whichbyte(size_t __pos) _GLIBCXX_NOEXCEPT { return (__pos % _GLIBCXX_BITSET_BITS_PER_WORD) / __CHAR_BIT__; } static _GLIBCXX_CONSTEXPR size_t _S_whichbit(size_t __pos) _GLIBCXX_NOEXCEPT { return __pos % _GLIBCXX_BITSET_BITS_PER_WORD; } static _GLIBCXX_CONSTEXPR _WordT _S_maskbit(size_t __pos) _GLIBCXX_NOEXCEPT { return (static_cast<_WordT>(1)) << _S_whichbit(__pos); } // This would normally give access to the data. The bounds-checking // in the bitset class will prevent the user from getting this far, // but (1) it must still return an lvalue to compile, and (2) the // user might call _Unchecked_set directly, in which case this /needs/ // to fail. Let's not penalize zero-length users unless they actually // make an unchecked call; all the memory ugliness is therefore // localized to this single should-never-get-this-far function. _WordT& _M_getword(size_t) _GLIBCXX_NOEXCEPT { __throw_out_of_range(__N("_Base_bitset::_M_getword")); return *new _WordT; } _GLIBCXX_CONSTEXPR _WordT _M_getword(size_t) const _GLIBCXX_NOEXCEPT { return 0; } _GLIBCXX_CONSTEXPR _WordT _M_hiword() const _GLIBCXX_NOEXCEPT { return 0; } void _M_do_and(const _Base_bitset<0>&) _GLIBCXX_NOEXCEPT { } void _M_do_or(const _Base_bitset<0>&) _GLIBCXX_NOEXCEPT { } void _M_do_xor(const _Base_bitset<0>&) _GLIBCXX_NOEXCEPT { } void _M_do_left_shift(size_t) _GLIBCXX_NOEXCEPT { } void _M_do_right_shift(size_t) _GLIBCXX_NOEXCEPT { } void _M_do_flip() _GLIBCXX_NOEXCEPT { } void _M_do_set() _GLIBCXX_NOEXCEPT { } void _M_do_reset() _GLIBCXX_NOEXCEPT { } // Are all empty bitsets equal to each other? Are they equal to // themselves? How to compare a thing which has no state? What is // the sound of one zero-length bitset clapping? bool _M_is_equal(const _Base_bitset<0>&) const _GLIBCXX_NOEXCEPT { return true; } template bool _M_are_all() const _GLIBCXX_NOEXCEPT { return true; } bool _M_is_any() const _GLIBCXX_NOEXCEPT { return false; } size_t _M_do_count() const _GLIBCXX_NOEXCEPT { return 0; } unsigned long _M_do_to_ulong() const _GLIBCXX_NOEXCEPT { return 0; } #if __cplusplus >= 201103L unsigned long long _M_do_to_ullong() const noexcept { return 0; } #endif // Normally "not found" is the size, but that could also be // misinterpreted as an index in this corner case. Oh well. size_t _M_do_find_first(size_t) const _GLIBCXX_NOEXCEPT { return 0; } size_t _M_do_find_next(size_t, size_t) const _GLIBCXX_NOEXCEPT { return 0; } }; // Helper class to zero out the unused high-order bits in the highest word. template struct _Sanitize { typedef unsigned long _WordT; static void _S_do_sanitize(_WordT& __val) _GLIBCXX_NOEXCEPT { __val &= ~((~static_cast<_WordT>(0)) << _Extrabits); } }; template<> struct _Sanitize<0> { typedef unsigned long _WordT; static void _S_do_sanitize(_WordT) _GLIBCXX_NOEXCEPT { } }; #if __cplusplus >= 201103L template struct _Sanitize_val { static constexpr unsigned long long _S_do_sanitize_val(unsigned long long __val) { return __val; } }; template struct _Sanitize_val<_Nb, true> { static constexpr unsigned long long _S_do_sanitize_val(unsigned long long __val) { return __val & ~((~static_cast(0)) << _Nb); } }; #endif /** * @brief The %bitset class represents a @e fixed-size sequence of bits. * @ingroup utilities * * (Note that %bitset does @e not meet the formal requirements of a * container. Mainly, it lacks iterators.) * * The template argument, @a Nb, may be any non-negative number, * specifying the number of bits (e.g., "0", "12", "1024*1024"). * * In the general unoptimized case, storage is allocated in word-sized * blocks. Let B be the number of bits in a word, then (Nb+(B-1))/B * words will be used for storage. B - Nb%B bits are unused. (They are * the high-order bits in the highest word.) It is a class invariant * that those unused bits are always zero. * * If you think of %bitset as a simple array of bits, be * aware that your mental picture is reversed: a %bitset behaves * the same way as bits in integers do, with the bit at index 0 in * the least significant / right-hand position, and the bit at * index Nb-1 in the most significant / left-hand position. * Thus, unlike other containers, a %bitset's index counts from * right to left, to put it very loosely. * * This behavior is preserved when translating to and from strings. For * example, the first line of the following program probably prints * b('a') is 0001100001 on a modern ASCII system. * * @code * #include * #include * #include * * using namespace std; * * int main() * { * long a = 'a'; * bitset<10> b(a); * * cout << "b('a') is " << b << endl; * * ostringstream s; * s << b; * string str = s.str(); * cout << "index 3 in the string is " << str[3] << " but\n" * << "index 3 in the bitset is " << b[3] << endl; * } * @endcode * * Also see: * https://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_containers.html * for a description of extensions. * * Most of the actual code isn't contained in %bitset<> itself, but in the * base class _Base_bitset. The base class works with whole words, not with * individual bits. This allows us to specialize _Base_bitset for the * important special case where the %bitset is only a single word. * * Extra confusion can result due to the fact that the storage for * _Base_bitset @e is a regular array, and is indexed as such. This is * carefully encapsulated. */ template class bitset : private _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> { private: typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base; typedef unsigned long _WordT; template void _M_check_initial_position(const std::basic_string<_CharT, _Traits, _Alloc>& __s, size_t __position) const { if (__position > __s.size()) __throw_out_of_range_fmt(__N("bitset::bitset: __position " "(which is %zu) > __s.size() " "(which is %zu)"), __position, __s.size()); } void _M_check(size_t __position, const char *__s) const { if (__position >= _Nb) __throw_out_of_range_fmt(__N("%s: __position (which is %zu) " ">= _Nb (which is %zu)"), __s, __position, _Nb); } void _M_do_sanitize() _GLIBCXX_NOEXCEPT { typedef _Sanitize<_Nb % _GLIBCXX_BITSET_BITS_PER_WORD> __sanitize_type; __sanitize_type::_S_do_sanitize(this->_M_hiword()); } #if __cplusplus >= 201103L friend struct std::hash; #endif public: /** * This encapsulates the concept of a single bit. An instance of this * class is a proxy for an actual bit; this way the individual bit * operations are done as faster word-size bitwise instructions. * * Most users will never need to use this class directly; conversions * to and from bool are automatic and should be transparent. Overloaded * operators help to preserve the illusion. * * (On a typical system, this bit %reference is 64 * times the size of an actual bit. Ha.) */ class reference { friend class bitset; _WordT* _M_wp; size_t _M_bpos; // left undefined reference(); public: reference(bitset& __b, size_t __pos) _GLIBCXX_NOEXCEPT { _M_wp = &__b._M_getword(__pos); _M_bpos = _Base::_S_whichbit(__pos); } ~reference() _GLIBCXX_NOEXCEPT { } // For b[i] = __x; reference& operator=(bool __x) _GLIBCXX_NOEXCEPT { if (__x) *_M_wp |= _Base::_S_maskbit(_M_bpos); else *_M_wp &= ~_Base::_S_maskbit(_M_bpos); return *this; } // For b[i] = b[__j]; reference& operator=(const reference& __j) _GLIBCXX_NOEXCEPT { if ((*(__j._M_wp) & _Base::_S_maskbit(__j._M_bpos))) *_M_wp |= _Base::_S_maskbit(_M_bpos); else *_M_wp &= ~_Base::_S_maskbit(_M_bpos); return *this; } // Flips the bit bool operator~() const _GLIBCXX_NOEXCEPT { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; } // For __x = b[i]; operator bool() const _GLIBCXX_NOEXCEPT { return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; } // For b[i].flip(); reference& flip() _GLIBCXX_NOEXCEPT { *_M_wp ^= _Base::_S_maskbit(_M_bpos); return *this; } }; friend class reference; // 23.3.5.1 constructors: /// All bits set to zero. _GLIBCXX_CONSTEXPR bitset() _GLIBCXX_NOEXCEPT { } /// Initial bits bitwise-copied from a single word (others set to zero). #if __cplusplus >= 201103L constexpr bitset(unsigned long long __val) noexcept : _Base(_Sanitize_val<_Nb>::_S_do_sanitize_val(__val)) { } #else bitset(unsigned long __val) : _Base(__val) { _M_do_sanitize(); } #endif /** * Use a subset of a string. * @param __s A string of @a 0 and @a 1 characters. * @param __position Index of the first character in @a __s to use; * defaults to zero. * @throw std::out_of_range If @a pos is bigger the size of @a __s. * @throw std::invalid_argument If a character appears in the string * which is neither @a 0 nor @a 1. */ template explicit bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s, size_t __position = 0) : _Base() { _M_check_initial_position(__s, __position); _M_copy_from_string(__s, __position, std::basic_string<_CharT, _Traits, _Alloc>::npos, _CharT('0'), _CharT('1')); } /** * Use a subset of a string. * @param __s A string of @a 0 and @a 1 characters. * @param __position Index of the first character in @a __s to use. * @param __n The number of characters to copy. * @throw std::out_of_range If @a __position is bigger the size * of @a __s. * @throw std::invalid_argument If a character appears in the string * which is neither @a 0 nor @a 1. */ template bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s, size_t __position, size_t __n) : _Base() { _M_check_initial_position(__s, __position); _M_copy_from_string(__s, __position, __n, _CharT('0'), _CharT('1')); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 396. what are characters zero and one. template bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s, size_t __position, size_t __n, _CharT __zero, _CharT __one = _CharT('1')) : _Base() { _M_check_initial_position(__s, __position); _M_copy_from_string(__s, __position, __n, __zero, __one); } #if __cplusplus >= 201103L /** * Construct from a character %array. * @param __str An %array of characters @a zero and @a one. * @param __n The number of characters to use. * @param __zero The character corresponding to the value 0. * @param __one The character corresponding to the value 1. * @throw std::invalid_argument If a character appears in the string * which is neither @a __zero nor @a __one. */ template explicit bitset(const _CharT* __str, typename std::basic_string<_CharT>::size_type __n = std::basic_string<_CharT>::npos, _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')) : _Base() { if (!__str) __throw_logic_error(__N("bitset::bitset(const _CharT*, ...)")); if (__n == std::basic_string<_CharT>::npos) __n = std::char_traits<_CharT>::length(__str); _M_copy_from_ptr<_CharT, std::char_traits<_CharT>>(__str, __n, 0, __n, __zero, __one); } #endif // 23.3.5.2 bitset operations: //@{ /** * Operations on bitsets. * @param __rhs A same-sized bitset. * * These should be self-explanatory. */ bitset<_Nb>& operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT { this->_M_do_and(__rhs); return *this; } bitset<_Nb>& operator|=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT { this->_M_do_or(__rhs); return *this; } bitset<_Nb>& operator^=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT { this->_M_do_xor(__rhs); return *this; } //@} //@{ /** * Operations on bitsets. * @param __position The number of places to shift. * * These should be self-explanatory. */ bitset<_Nb>& operator<<=(size_t __position) _GLIBCXX_NOEXCEPT { if (__builtin_expect(__position < _Nb, 1)) { this->_M_do_left_shift(__position); this->_M_do_sanitize(); } else this->_M_do_reset(); return *this; } bitset<_Nb>& operator>>=(size_t __position) _GLIBCXX_NOEXCEPT { if (__builtin_expect(__position < _Nb, 1)) { this->_M_do_right_shift(__position); this->_M_do_sanitize(); } else this->_M_do_reset(); return *this; } //@} //@{ /** * These versions of single-bit set, reset, flip, and test are * extensions from the SGI version. They do no range checking. * @ingroup SGIextensions */ bitset<_Nb>& _Unchecked_set(size_t __pos) _GLIBCXX_NOEXCEPT { this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); return *this; } bitset<_Nb>& _Unchecked_set(size_t __pos, int __val) _GLIBCXX_NOEXCEPT { if (__val) this->_M_getword(__pos) |= _Base::_S_maskbit(__pos); else this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); return *this; } bitset<_Nb>& _Unchecked_reset(size_t __pos) _GLIBCXX_NOEXCEPT { this->_M_getword(__pos) &= ~_Base::_S_maskbit(__pos); return *this; } bitset<_Nb>& _Unchecked_flip(size_t __pos) _GLIBCXX_NOEXCEPT { this->_M_getword(__pos) ^= _Base::_S_maskbit(__pos); return *this; } _GLIBCXX_CONSTEXPR bool _Unchecked_test(size_t __pos) const _GLIBCXX_NOEXCEPT { return ((this->_M_getword(__pos) & _Base::_S_maskbit(__pos)) != static_cast<_WordT>(0)); } //@} // Set, reset, and flip. /** * @brief Sets every bit to true. */ bitset<_Nb>& set() _GLIBCXX_NOEXCEPT { this->_M_do_set(); this->_M_do_sanitize(); return *this; } /** * @brief Sets a given bit to a particular value. * @param __position The index of the bit. * @param __val Either true or false, defaults to true. * @throw std::out_of_range If @a pos is bigger the size of the %set. */ bitset<_Nb>& set(size_t __position, bool __val = true) { this->_M_check(__position, __N("bitset::set")); return _Unchecked_set(__position, __val); } /** * @brief Sets every bit to false. */ bitset<_Nb>& reset() _GLIBCXX_NOEXCEPT { this->_M_do_reset(); return *this; } /** * @brief Sets a given bit to false. * @param __position The index of the bit. * @throw std::out_of_range If @a pos is bigger the size of the %set. * * Same as writing @c set(pos,false). */ bitset<_Nb>& reset(size_t __position) { this->_M_check(__position, __N("bitset::reset")); return _Unchecked_reset(__position); } /** * @brief Toggles every bit to its opposite value. */ bitset<_Nb>& flip() _GLIBCXX_NOEXCEPT { this->_M_do_flip(); this->_M_do_sanitize(); return *this; } /** * @brief Toggles a given bit to its opposite value. * @param __position The index of the bit. * @throw std::out_of_range If @a pos is bigger the size of the %set. */ bitset<_Nb>& flip(size_t __position) { this->_M_check(__position, __N("bitset::flip")); return _Unchecked_flip(__position); } /// See the no-argument flip(). bitset<_Nb> operator~() const _GLIBCXX_NOEXCEPT { return bitset<_Nb>(*this).flip(); } //@{ /** * @brief Array-indexing support. * @param __position Index into the %bitset. * @return A bool for a const %bitset. For non-const * bitsets, an instance of the reference proxy class. * @note These operators do no range checking and throw no exceptions, * as required by DR 11 to the standard. * * _GLIBCXX_RESOLVE_LIB_DEFECTS Note that this implementation already * resolves DR 11 (items 1 and 2), but does not do the range-checking * required by that DR's resolution. -pme * The DR has since been changed: range-checking is a precondition * (users' responsibility), and these functions must not throw. -pme */ reference operator[](size_t __position) { return reference(*this, __position); } _GLIBCXX_CONSTEXPR bool operator[](size_t __position) const { return _Unchecked_test(__position); } //@} /** * @brief Returns a numerical interpretation of the %bitset. * @return The integral equivalent of the bits. * @throw std::overflow_error If there are too many bits to be * represented in an @c unsigned @c long. */ unsigned long to_ulong() const { return this->_M_do_to_ulong(); } #if __cplusplus >= 201103L unsigned long long to_ullong() const { return this->_M_do_to_ullong(); } #endif /** * @brief Returns a character interpretation of the %bitset. * @return The string equivalent of the bits. * * Note the ordering of the bits: decreasing character positions * correspond to increasing bit positions (see the main class notes for * an example). */ template std::basic_string<_CharT, _Traits, _Alloc> to_string() const { std::basic_string<_CharT, _Traits, _Alloc> __result; _M_copy_to_string(__result, _CharT('0'), _CharT('1')); return __result; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 396. what are characters zero and one. template std::basic_string<_CharT, _Traits, _Alloc> to_string(_CharT __zero, _CharT __one = _CharT('1')) const { std::basic_string<_CharT, _Traits, _Alloc> __result; _M_copy_to_string(__result, __zero, __one); return __result; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 434. bitset::to_string() hard to use. template std::basic_string<_CharT, _Traits, std::allocator<_CharT> > to_string() const { return to_string<_CharT, _Traits, std::allocator<_CharT> >(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 853. to_string needs updating with zero and one. template std::basic_string<_CharT, _Traits, std::allocator<_CharT> > to_string(_CharT __zero, _CharT __one = _CharT('1')) const { return to_string<_CharT, _Traits, std::allocator<_CharT> >(__zero, __one); } template std::basic_string<_CharT, std::char_traits<_CharT>, std::allocator<_CharT> > to_string() const { return to_string<_CharT, std::char_traits<_CharT>, std::allocator<_CharT> >(); } template std::basic_string<_CharT, std::char_traits<_CharT>, std::allocator<_CharT> > to_string(_CharT __zero, _CharT __one = _CharT('1')) const { return to_string<_CharT, std::char_traits<_CharT>, std::allocator<_CharT> >(__zero, __one); } std::basic_string, std::allocator > to_string() const { return to_string, std::allocator >(); } std::basic_string, std::allocator > to_string(char __zero, char __one = '1') const { return to_string, std::allocator >(__zero, __one); } // Helper functions for string operations. template void _M_copy_from_ptr(const _CharT*, size_t, size_t, size_t, _CharT, _CharT); template void _M_copy_from_string(const std::basic_string<_CharT, _Traits, _Alloc>& __s, size_t __pos, size_t __n, _CharT __zero, _CharT __one) { _M_copy_from_ptr<_CharT, _Traits>(__s.data(), __s.size(), __pos, __n, __zero, __one); } template void _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>&, _CharT, _CharT) const; // NB: Backward compat. template void _M_copy_from_string(const std::basic_string<_CharT, _Traits, _Alloc>& __s, size_t __pos, size_t __n) { _M_copy_from_string(__s, __pos, __n, _CharT('0'), _CharT('1')); } template void _M_copy_to_string(std::basic_string<_CharT, _Traits,_Alloc>& __s) const { _M_copy_to_string(__s, _CharT('0'), _CharT('1')); } /// Returns the number of bits which are set. size_t count() const _GLIBCXX_NOEXCEPT { return this->_M_do_count(); } /// Returns the total number of bits. _GLIBCXX_CONSTEXPR size_t size() const _GLIBCXX_NOEXCEPT { return _Nb; } //@{ /// These comparisons for equality/inequality are, well, @e bitwise. bool operator==(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT { return this->_M_is_equal(__rhs); } bool operator!=(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT { return !this->_M_is_equal(__rhs); } //@} /** * @brief Tests the value of a bit. * @param __position The index of a bit. * @return The value at @a pos. * @throw std::out_of_range If @a pos is bigger the size of the %set. */ bool test(size_t __position) const { this->_M_check(__position, __N("bitset::test")); return _Unchecked_test(__position); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 693. std::bitset::all() missing. /** * @brief Tests whether all the bits are on. * @return True if all the bits are set. */ bool all() const _GLIBCXX_NOEXCEPT { return this->template _M_are_all<_Nb>(); } /** * @brief Tests whether any of the bits are on. * @return True if at least one bit is set. */ bool any() const _GLIBCXX_NOEXCEPT { return this->_M_is_any(); } /** * @brief Tests whether any of the bits are on. * @return True if none of the bits are set. */ bool none() const _GLIBCXX_NOEXCEPT { return !this->_M_is_any(); } //@{ /// Self-explanatory. bitset<_Nb> operator<<(size_t __position) const _GLIBCXX_NOEXCEPT { return bitset<_Nb>(*this) <<= __position; } bitset<_Nb> operator>>(size_t __position) const _GLIBCXX_NOEXCEPT { return bitset<_Nb>(*this) >>= __position; } //@} /** * @brief Finds the index of the first "on" bit. * @return The index of the first bit set, or size() if not found. * @ingroup SGIextensions * @sa _Find_next */ size_t _Find_first() const _GLIBCXX_NOEXCEPT { return this->_M_do_find_first(_Nb); } /** * @brief Finds the index of the next "on" bit after prev. * @return The index of the next bit set, or size() if not found. * @param __prev Where to start searching. * @ingroup SGIextensions * @sa _Find_first */ size_t _Find_next(size_t __prev) const _GLIBCXX_NOEXCEPT { return this->_M_do_find_next(__prev, _Nb); } }; // Definitions of non-inline member functions. template template void bitset<_Nb>:: _M_copy_from_ptr(const _CharT* __s, size_t __len, size_t __pos, size_t __n, _CharT __zero, _CharT __one) { reset(); const size_t __nbits = std::min(_Nb, std::min(__n, size_t(__len - __pos))); for (size_t __i = __nbits; __i > 0; --__i) { const _CharT __c = __s[__pos + __nbits - __i]; if (_Traits::eq(__c, __zero)) ; else if (_Traits::eq(__c, __one)) _Unchecked_set(__i - 1); else __throw_invalid_argument(__N("bitset::_M_copy_from_ptr")); } } template template void bitset<_Nb>:: _M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>& __s, _CharT __zero, _CharT __one) const { __s.assign(_Nb, __zero); for (size_t __i = _Nb; __i > 0; --__i) if (_Unchecked_test(__i - 1)) _Traits::assign(__s[_Nb - __i], __one); } // 23.3.5.3 bitset operations: //@{ /** * @brief Global bitwise operations on bitsets. * @param __x A bitset. * @param __y A bitset of the same size as @a __x. * @return A new bitset. * * These should be self-explanatory. */ template inline bitset<_Nb> operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT { bitset<_Nb> __result(__x); __result &= __y; return __result; } template inline bitset<_Nb> operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT { bitset<_Nb> __result(__x); __result |= __y; return __result; } template inline bitset<_Nb> operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT { bitset<_Nb> __result(__x); __result ^= __y; return __result; } //@} //@{ /** * @brief Global I/O operators for bitsets. * * Direct I/O between streams and bitsets is supported. Output is * straightforward. Input will skip whitespace, only accept @a 0 and @a 1 * characters, and will only extract as many digits as the %bitset will * hold. */ template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x) { typedef typename _Traits::char_type char_type; typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; std::basic_string<_CharT, _Traits> __tmp; __tmp.reserve(_Nb); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 303. Bitset input operator underspecified const char_type __zero = __is.widen('0'); const char_type __one = __is.widen('1'); typename __ios_base::iostate __state = __ios_base::goodbit; typename __istream_type::sentry __sentry(__is); if (__sentry) { __try { for (size_t __i = _Nb; __i > 0; --__i) { static typename _Traits::int_type __eof = _Traits::eof(); typename _Traits::int_type __c1 = __is.rdbuf()->sbumpc(); if (_Traits::eq_int_type(__c1, __eof)) { __state |= __ios_base::eofbit; break; } else { const char_type __c2 = _Traits::to_char_type(__c1); if (_Traits::eq(__c2, __zero)) __tmp.push_back(__zero); else if (_Traits::eq(__c2, __one)) __tmp.push_back(__one); else if (_Traits:: eq_int_type(__is.rdbuf()->sputbackc(__c2), __eof)) { __state |= __ios_base::failbit; break; } } } } __catch(__cxxabiv1::__forced_unwind&) { __is._M_setstate(__ios_base::badbit); __throw_exception_again; } __catch(...) { __is._M_setstate(__ios_base::badbit); } } if (__tmp.empty() && _Nb) __state |= __ios_base::failbit; else __x._M_copy_from_string(__tmp, static_cast(0), _Nb, __zero, __one); if (__state) __is.setstate(__state); return __is; } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const bitset<_Nb>& __x) { std::basic_string<_CharT, _Traits> __tmp; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 396. what are characters zero and one. const ctype<_CharT>& __ct = use_facet >(__os.getloc()); __x._M_copy_to_string(__tmp, __ct.widen('0'), __ct.widen('1')); return __os << __tmp; } //@} _GLIBCXX_END_NAMESPACE_CONTAINER } // namespace std #undef _GLIBCXX_BITSET_WORDS #undef _GLIBCXX_BITSET_BITS_PER_WORD #undef _GLIBCXX_BITSET_BITS_PER_ULL #if __cplusplus >= 201103L namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // DR 1182. /// std::hash specialization for bitset. template struct hash<_GLIBCXX_STD_C::bitset<_Nb>> : public __hash_base> { size_t operator()(const _GLIBCXX_STD_C::bitset<_Nb>& __b) const noexcept { const size_t __clength = (_Nb + __CHAR_BIT__ - 1) / __CHAR_BIT__; return std::_Hash_impl::hash(__b._M_getdata(), __clength); } }; template<> struct hash<_GLIBCXX_STD_C::bitset<0>> : public __hash_base> { size_t operator()(const _GLIBCXX_STD_C::bitset<0>&) const noexcept { return 0; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #ifdef _GLIBCXX_DEBUG # include #endif #ifdef _GLIBCXX_PROFILE # include #endif #endif /* _GLIBCXX_BITSET */ 8/memory000064400000011147152526447520006166 0ustar00// -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * Copyright (c) 1997-1999 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ /** @file include/memory * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_MEMORY #define _GLIBCXX_MEMORY 1 #pragma GCC system_header /** * @defgroup memory Memory * @ingroup utilities * * Components for memory allocation, deallocation, and management. */ /** * @defgroup pointer_abstractions Pointer Abstractions * @ingroup memory * * Smart pointers, etc. */ #include #include #include #include #include #include #if __cplusplus >= 201103L # include // std::exception # include // std::type_info in get_deleter # include // std::basic_ostream # include # include # include # include // std::less # include # include # include # include # include # include # if _GLIBCXX_USE_DEPRECATED # include # endif #else # include #endif #if __cplusplus >= 201103L # include # ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Fit aligned storage in buffer. * * [ptr.align] * * This function tries to fit @a __size bytes of storage with alignment * @a __align into the buffer @a __ptr of size @a __space bytes. If such * a buffer fits then @a __ptr is changed to point to the first byte of the * aligned storage and @a __space is reduced by the bytes used for alignment. * * @param __align A fundamental or extended alignment value. * @param __size Size of the aligned storage required. * @param __ptr Pointer to a buffer of @a __space bytes. * @param __space Size of the buffer pointed to by @a __ptr. * @return the updated pointer if the aligned storage fits, otherwise nullptr. */ inline void* align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept { const auto __intptr = reinterpret_cast(__ptr); const auto __aligned = (__intptr - 1u + __align) & -__align; const auto __diff = __aligned - __intptr; if ((__size + __diff) > __space) return nullptr; else { __space -= __diff; return __ptr = reinterpret_cast(__aligned); } } // 20.7.4 [util.dynamic.safety], pointer safety enum class pointer_safety { relaxed, preferred, strict }; inline void declare_reachable(void*) { } template inline _Tp* undeclare_reachable(_Tp* __p) { return __p; } inline void declare_no_pointers(char*, size_t) { } inline void undeclare_no_pointers(char*, size_t) { } inline pointer_safety get_pointer_safety() noexcept { return pointer_safety::relaxed; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif /* _GLIBCXX_MEMORY */ 8/ctime000064400000004115152526447520005754 0ustar00// -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/ctime * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c time.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 20.5 Date and time // #pragma GCC system_header #include #include #ifndef _GLIBCXX_CTIME #define _GLIBCXX_CTIME 1 // Get rid of those macros defined in in lieu of real functions. #undef clock #undef difftime #undef mktime #undef time #undef asctime #undef ctime #undef gmtime #undef localtime #undef strftime namespace std { using ::clock_t; using ::time_t; using ::tm; using ::clock; using ::difftime; using ::mktime; using ::time; using ::asctime; using ::ctime; using ::gmtime; using ::localtime; using ::strftime; } // namespace #endif 8/stdlib.h000064400000004310152526447520006357 0ustar00// -*- C++ -*- compatibility header. // Copyright (C) 2002-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file stdlib.h * This is a Standard C++ Library header. */ #if !defined __cplusplus || defined _GLIBCXX_INCLUDE_NEXT_C_HEADERS # include_next #else #ifndef _GLIBCXX_STDLIB_H #define _GLIBCXX_STDLIB_H 1 # include using std::abort; using std::atexit; using std::exit; #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT using std::at_quick_exit; # endif # ifdef _GLIBCXX_HAVE_QUICK_EXIT using std::quick_exit; # endif #endif #if _GLIBCXX_HOSTED using std::div_t; using std::ldiv_t; using std::abs; using std::atof; using std::atoi; using std::atol; using std::bsearch; using std::calloc; using std::div; using std::free; using std::getenv; using std::labs; using std::ldiv; using std::malloc; #ifdef _GLIBCXX_HAVE_MBSTATE_T using std::mblen; using std::mbstowcs; using std::mbtowc; #endif // _GLIBCXX_HAVE_MBSTATE_T using std::qsort; using std::rand; using std::realloc; using std::srand; using std::strtod; using std::strtol; using std::strtoul; using std::system; #ifdef _GLIBCXX_USE_WCHAR_T using std::wcstombs; using std::wctomb; #endif // _GLIBCXX_USE_WCHAR_T #endif #endif // _GLIBCXX_STDLIB_H #endif // __cplusplus 8/deque000064400000005151152526447520005757 0ustar00// -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file include/deque * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_DEQUE #define _GLIBCXX_DEQUE 1 #pragma GCC system_header #include #include #include #include #include #include #include #ifdef _GLIBCXX_DEBUG # include #endif #ifdef _GLIBCXX_PROFILE # include #endif #endif /* _GLIBCXX_DEQUE */ 8/ext/atomicity.h000064400000006665152526447520007717 0ustar00// Support for atomic operations -*- C++ -*- // Copyright (C) 2004-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ext/atomicity.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _GLIBCXX_ATOMICITY_H #define _GLIBCXX_ATOMICITY_H 1 #pragma GCC system_header #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Functions for portable atomic access. // To abstract locking primitives across all thread policies, use: // __exchange_and_add_dispatch // __atomic_add_dispatch #ifdef _GLIBCXX_ATOMIC_BUILTINS static inline _Atomic_word __exchange_and_add(volatile _Atomic_word* __mem, int __val) { return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); } static inline void __atomic_add(volatile _Atomic_word* __mem, int __val) { __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); } #else _Atomic_word __attribute__ ((__unused__)) __exchange_and_add(volatile _Atomic_word*, int) throw (); void __attribute__ ((__unused__)) __atomic_add(volatile _Atomic_word*, int) throw (); #endif static inline _Atomic_word __exchange_and_add_single(_Atomic_word* __mem, int __val) { _Atomic_word __result = *__mem; *__mem += __val; return __result; } static inline void __atomic_add_single(_Atomic_word* __mem, int __val) { *__mem += __val; } static inline _Atomic_word __attribute__ ((__unused__)) __exchange_and_add_dispatch(_Atomic_word* __mem, int __val) { #ifdef __GTHREADS if (__gthread_active_p()) return __exchange_and_add(__mem, __val); else return __exchange_and_add_single(__mem, __val); #else return __exchange_and_add_single(__mem, __val); #endif } static inline void __attribute__ ((__unused__)) __atomic_add_dispatch(_Atomic_word* __mem, int __val) { #ifdef __GTHREADS if (__gthread_active_p()) __atomic_add(__mem, __val); else __atomic_add_single(__mem, __val); #else __atomic_add_single(__mem, __val); #endif } _GLIBCXX_END_NAMESPACE_VERSION } // namespace // Even if the CPU doesn't need a memory barrier, we need to ensure // that the compiler doesn't reorder memory accesses across the // barriers. #ifndef _GLIBCXX_READ_MEM_BARRIER #define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence (__ATOMIC_ACQUIRE) #endif #ifndef _GLIBCXX_WRITE_MEM_BARRIER #define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence (__ATOMIC_RELEASE) #endif #endif 8/ext/iterator000064400000007677152526447520007324 0ustar00// HP/SGI iterator extensions -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file ext/iterator * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_ITERATOR #define _EXT_ITERATOR 1 #pragma GCC system_header #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // There are two signatures for distance. In addition to the one // taking two iterators and returning a result, there is another // taking two iterators and a reference-to-result variable, and // returning nothing. The latter seems to be an SGI extension. // -- pedwards template inline void __distance(_InputIterator __first, _InputIterator __last, _Distance& __n, std::input_iterator_tag) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) while (__first != __last) { ++__first; ++__n; } } template inline void __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, _Distance& __n, std::random_access_iterator_tag) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) __n += __last - __first; } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template inline void distance(_InputIterator __first, _InputIterator __last, _Distance& __n) { // concept requirements -- taken care of in __distance __distance(__first, __last, __n, std::__iterator_category(__first)); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/ext/new_allocator.h000064400000011305152526447520010531 0ustar00// Allocator that wraps operator new -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ext/new_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _NEW_ALLOCATOR_H #define _NEW_ALLOCATOR_H 1 #include #include #include #include #if __cplusplus >= 201103L #include #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; /** * @brief An allocator that uses global new, as per [20.4]. * @ingroup allocators * * This is precisely the allocator defined in the C++ Standard. * - all allocation calls operator new * - all deallocation calls operator delete * * @tparam _Tp Type of allocated object. */ template class new_allocator { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; template struct rebind { typedef new_allocator<_Tp1> other; }; #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. propagate_on_container_move_assignment typedef std::true_type propagate_on_container_move_assignment; #endif new_allocator() _GLIBCXX_USE_NOEXCEPT { } new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { } template new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { } ~new_allocator() _GLIBCXX_USE_NOEXCEPT { } pointer address(reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } // NB: __n is permitted to be 0. The C++ standard says nothing // about what the return value is when __n == 0. pointer allocate(size_type __n, const void* = static_cast(0)) { if (__n > this->max_size()) std::__throw_bad_alloc(); #if __cpp_aligned_new if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { std::align_val_t __al = std::align_val_t(alignof(_Tp)); return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), __al)); } #endif return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); } // __p is not permitted to be a null pointer. void deallocate(pointer __p, size_type) { #if __cpp_aligned_new if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { ::operator delete(__p, std::align_val_t(alignof(_Tp))); return; } #endif ::operator delete(__p); } size_type max_size() const _GLIBCXX_USE_NOEXCEPT { return size_t(-1) / sizeof(_Tp); } #if __cplusplus >= 201103L template void construct(_Up* __p, _Args&&... __args) { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } template void destroy(_Up* __p) { __p->~_Up(); } #else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) _Tp(__val); } void destroy(pointer __p) { __p->~_Tp(); } #endif }; template inline bool operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&) { return true; } template inline bool operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&) { return false; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/ext/random000064400000331443152526447520006742 0ustar00// Random number extensions -*- C++ -*- // Copyright (C) 2012-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ext/random * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_RANDOM #define _EXT_RANDOM 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #ifdef __SSE2__ # include #endif #if defined(_GLIBCXX_USE_C99_STDINT_TR1) && defined(UINT32_C) namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Mersenne twister implementation optimized for vector operations. * * Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/ */ template class simd_fast_mersenne_twister_engine { static_assert(std::is_unsigned<_UIntType>::value, "template argument " "substituting _UIntType not an unsigned integral type"); static_assert(__sr1 < 32, "first right shift too large"); static_assert(__sr2 < 16, "second right shift too large"); static_assert(__sl1 < 32, "first left shift too large"); static_assert(__sl2 < 16, "second left shift too large"); public: typedef _UIntType result_type; private: static constexpr size_t m_w = sizeof(result_type) * 8; static constexpr size_t _M_nstate = __m / 128 + 1; static constexpr size_t _M_nstate32 = _M_nstate * 4; static_assert(std::is_unsigned<_UIntType>::value, "template argument " "substituting _UIntType not an unsigned integral type"); static_assert(__pos1 < _M_nstate, "POS1 not smaller than state size"); static_assert(16 % sizeof(_UIntType) == 0, "UIntType size must divide 16"); public: static constexpr size_t state_size = _M_nstate * (16 / sizeof(result_type)); static constexpr result_type default_seed = 5489u; // constructors and member function explicit simd_fast_mersenne_twister_engine(result_type __sd = default_seed) { seed(__sd); } template::value> ::type> explicit simd_fast_mersenne_twister_engine(_Sseq& __q) { seed(__q); } void seed(result_type __sd = default_seed); template typename std::enable_if::value>::type seed(_Sseq& __q); static constexpr result_type min() { return 0; } static constexpr result_type max() { return std::numeric_limits::max(); } void discard(unsigned long long __z); result_type operator()() { if (__builtin_expect(_M_pos >= state_size, 0)) _M_gen_rand(); return _M_stateT[_M_pos++]; } template friend bool operator==(const simd_fast_mersenne_twister_engine<_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __lhs, const simd_fast_mersenne_twister_engine<_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __rhs); template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::simd_fast_mersenne_twister_engine <_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); private: union { #ifdef __SSE2__ __m128i _M_state[_M_nstate]; #endif #ifdef __ARM_NEON #ifdef __aarch64__ __Uint32x4_t _M_state[_M_nstate]; #endif #endif uint32_t _M_state32[_M_nstate32]; result_type _M_stateT[state_size]; } __attribute__ ((__aligned__ (16))); size_t _M_pos; void _M_gen_rand(void); void _M_period_certification(); }; template inline bool operator!=(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs, const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs) { return !(__lhs == __rhs); } /* Definitions for the SIMD-oriented Fast Mersenne Twister as defined * in the C implementation by Daito and Matsumoto, as both a 32-bit * and 64-bit version. */ typedef simd_fast_mersenne_twister_engine sfmt607; typedef simd_fast_mersenne_twister_engine sfmt607_64; typedef simd_fast_mersenne_twister_engine sfmt1279; typedef simd_fast_mersenne_twister_engine sfmt1279_64; typedef simd_fast_mersenne_twister_engine sfmt2281; typedef simd_fast_mersenne_twister_engine sfmt2281_64; typedef simd_fast_mersenne_twister_engine sfmt4253; typedef simd_fast_mersenne_twister_engine sfmt4253_64; typedef simd_fast_mersenne_twister_engine sfmt11213; typedef simd_fast_mersenne_twister_engine sfmt11213_64; typedef simd_fast_mersenne_twister_engine sfmt19937; typedef simd_fast_mersenne_twister_engine sfmt19937_64; typedef simd_fast_mersenne_twister_engine sfmt44497; typedef simd_fast_mersenne_twister_engine sfmt44497_64; typedef simd_fast_mersenne_twister_engine sfmt86243; typedef simd_fast_mersenne_twister_engine sfmt86243_64; typedef simd_fast_mersenne_twister_engine sfmt132049; typedef simd_fast_mersenne_twister_engine sfmt132049_64; typedef simd_fast_mersenne_twister_engine sfmt216091; typedef simd_fast_mersenne_twister_engine sfmt216091_64; #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /** * @brief A beta continuous distribution for random numbers. * * The formula for the beta probability density function is: * @f[ * p(x|\alpha,\beta) = \frac{1}{B(\alpha,\beta)} * x^{\alpha - 1} (1 - x)^{\beta - 1} * @f] */ template class beta_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef beta_distribution<_RealType> distribution_type; friend class beta_distribution<_RealType>; explicit param_type(_RealType __alpha_val = _RealType(1), _RealType __beta_val = _RealType(1)) : _M_alpha(__alpha_val), _M_beta(__beta_val) { __glibcxx_assert(_M_alpha > _RealType(0)); __glibcxx_assert(_M_beta > _RealType(0)); } _RealType alpha() const { return _M_alpha; } _RealType beta() const { return _M_beta; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return (__p1._M_alpha == __p2._M_alpha && __p1._M_beta == __p2._M_beta); } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); _RealType _M_alpha; _RealType _M_beta; }; public: /** * @brief Constructs a beta distribution with parameters * @f$\alpha@f$ and @f$\beta@f$. */ explicit beta_distribution(_RealType __alpha_val = _RealType(1), _RealType __beta_val = _RealType(1)) : _M_param(__alpha_val, __beta_val) { } explicit beta_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the @f$\alpha@f$ of the distribution. */ _RealType alpha() const { return _M_param.alpha(); } /** * @brief Returns the @f$\beta@f$ of the distribution. */ _RealType beta() const { return _M_param.beta(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return result_type(1); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two beta distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const beta_distribution& __d1, const beta_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %beta_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %beta_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::beta_distribution<_RealType1>& __x); /** * @brief Extracts a %beta_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %beta_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::beta_distribution<_RealType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two beta distributions are different. */ template inline bool operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1, const __gnu_cxx::beta_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A multi-variate normal continuous distribution for random numbers. * * The formula for the normal probability density function is * @f[ * p(\overrightarrow{x}|\overrightarrow{\mu },\Sigma) = * \frac{1}{\sqrt{(2\pi )^k\det(\Sigma))}} * e^{-\frac{1}{2}(\overrightarrow{x}-\overrightarrow{\mu})^\text{T} * \Sigma ^{-1}(\overrightarrow{x}-\overrightarrow{\mu})} * @f] * * where @f$\overrightarrow{x}@f$ and @f$\overrightarrow{\mu}@f$ are * vectors of dimension @f$k@f$ and @f$\Sigma@f$ is the covariance * matrix (which must be positive-definite). */ template class normal_mv_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); static_assert(_Dimen != 0, "dimension is zero"); public: /** The type of the range of the distribution. */ typedef std::array<_RealType, _Dimen> result_type; /** Parameter type. */ class param_type { static constexpr size_t _M_t_size = _Dimen * (_Dimen + 1) / 2; public: typedef normal_mv_distribution<_Dimen, _RealType> distribution_type; friend class normal_mv_distribution<_Dimen, _RealType>; param_type() { std::fill(_M_mean.begin(), _M_mean.end(), _RealType(0)); auto __it = _M_t.begin(); for (size_t __i = 0; __i < _Dimen; ++__i) { std::fill_n(__it, __i, _RealType(0)); __it += __i; *__it++ = _RealType(1); } } template param_type(_ForwardIterator1 __meanbegin, _ForwardIterator1 __meanend, _ForwardIterator2 __varcovbegin, _ForwardIterator2 __varcovend) { __glibcxx_function_requires(_ForwardIteratorConcept< _ForwardIterator1>) __glibcxx_function_requires(_ForwardIteratorConcept< _ForwardIterator2>) _GLIBCXX_DEBUG_ASSERT(std::distance(__meanbegin, __meanend) <= _Dimen); const auto __dist = std::distance(__varcovbegin, __varcovend); _GLIBCXX_DEBUG_ASSERT(__dist == _Dimen * _Dimen || __dist == _Dimen * (_Dimen + 1) / 2 || __dist == _Dimen); if (__dist == _Dimen * _Dimen) _M_init_full(__meanbegin, __meanend, __varcovbegin, __varcovend); else if (__dist == _Dimen * (_Dimen + 1) / 2) _M_init_lower(__meanbegin, __meanend, __varcovbegin, __varcovend); else { __glibcxx_assert(__dist == _Dimen); _M_init_diagonal(__meanbegin, __meanend, __varcovbegin, __varcovend); } } param_type(std::initializer_list<_RealType> __mean, std::initializer_list<_RealType> __varcov) { _GLIBCXX_DEBUG_ASSERT(__mean.size() <= _Dimen); _GLIBCXX_DEBUG_ASSERT(__varcov.size() == _Dimen * _Dimen || __varcov.size() == _Dimen * (_Dimen + 1) / 2 || __varcov.size() == _Dimen); if (__varcov.size() == _Dimen * _Dimen) _M_init_full(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end()); else if (__varcov.size() == _Dimen * (_Dimen + 1) / 2) _M_init_lower(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end()); else { __glibcxx_assert(__varcov.size() == _Dimen); _M_init_diagonal(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end()); } } std::array<_RealType, _Dimen> mean() const { return _M_mean; } std::array<_RealType, _M_t_size> varcov() const { return _M_t; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_mean == __p2._M_mean && __p1._M_t == __p2._M_t; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: template void _M_init_full(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend); template void _M_init_lower(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend); template void _M_init_diagonal(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varbegin, _InputIterator2 __varend); std::array<_RealType, _Dimen> _M_mean; std::array<_RealType, _M_t_size> _M_t; }; public: normal_mv_distribution() : _M_param(), _M_nd() { } template normal_mv_distribution(_ForwardIterator1 __meanbegin, _ForwardIterator1 __meanend, _ForwardIterator2 __varcovbegin, _ForwardIterator2 __varcovend) : _M_param(__meanbegin, __meanend, __varcovbegin, __varcovend), _M_nd() { } normal_mv_distribution(std::initializer_list<_RealType> __mean, std::initializer_list<_RealType> __varcov) : _M_param(__mean, __varcov), _M_nd() { } explicit normal_mv_distribution(const param_type& __p) : _M_param(__p), _M_nd() { } /** * @brief Resets the distribution state. */ void reset() { _M_nd.reset(); } /** * @brief Returns the mean of the distribution. */ result_type mean() const { return _M_param.mean(); } /** * @brief Returns the compact form of the variance/covariance * matrix of the distribution. */ std::array<_RealType, _Dimen * (_Dimen + 1) / 2> varcov() const { return _M_param.varcov(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { result_type __res; __res.fill(std::numeric_limits<_RealType>::lowest()); return __res; } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { result_type __res; __res.fill(std::numeric_limits<_RealType>::max()); return __res; } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { return this->__generate_impl(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { return this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two multi-variant normal distributions have * the same parameters and the sequences that would * be generated are equal. */ template friend bool operator==(const __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __d1, const __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __d2); /** * @brief Inserts a %normal_mv_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %normal_mv_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __x); /** * @brief Extracts a %normal_mv_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %normal_mv_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error * state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution<_RealType> _M_nd; }; /** * @brief Return true if two multi-variate normal distributions are * different. */ template inline bool operator!=(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d1, const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A Rice continuous distribution for random numbers. * * The formula for the Rice probability density function is * @f[ * p(x|\nu,\sigma) = \frac{x}{\sigma^2} * \exp\left(-\frac{x^2+\nu^2}{2\sigma^2}\right) * I_0\left(\frac{x \nu}{\sigma^2}\right) * @f] * where @f$I_0(z)@f$ is the modified Bessel function of the first kind * of order 0 and @f$\nu >= 0@f$ and @f$\sigma > 0@f$. * * * * * * *
Distribution Statistics
Mean@f$\sqrt{\pi/2}L_{1/2}(-\nu^2/2\sigma^2)@f$
Variance@f$2\sigma^2 + \nu^2 * + (\pi\sigma^2/2)L^2_{1/2}(-\nu^2/2\sigma^2)@f$
Range@f$[0, \infty)@f$
* where @f$L_{1/2}(x)@f$ is the Laguerre polynomial of order 1/2. */ template class rice_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef rice_distribution distribution_type; param_type(result_type __nu_val = result_type(0), result_type __sigma_val = result_type(1)) : _M_nu(__nu_val), _M_sigma(__sigma_val) { __glibcxx_assert(_M_nu >= result_type(0)); __glibcxx_assert(_M_sigma > result_type(0)); } result_type nu() const { return _M_nu; } result_type sigma() const { return _M_sigma; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_nu == __p2._M_nu && __p1._M_sigma == __p2._M_sigma; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_nu; result_type _M_sigma; }; /** * @brief Constructors. */ explicit rice_distribution(result_type __nu_val = result_type(0), result_type __sigma_val = result_type(1)) : _M_param(__nu_val, __sigma_val), _M_ndx(__nu_val, __sigma_val), _M_ndy(result_type(0), __sigma_val) { } explicit rice_distribution(const param_type& __p) : _M_param(__p), _M_ndx(__p.nu(), __p.sigma()), _M_ndy(result_type(0), __p.sigma()) { } /** * @brief Resets the distribution state. */ void reset() { _M_ndx.reset(); _M_ndy.reset(); } /** * @brief Return the parameters of the distribution. */ result_type nu() const { return _M_param.nu(); } result_type sigma() const { return _M_param.sigma(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { result_type __x = this->_M_ndx(__urng); result_type __y = this->_M_ndy(__urng); #if _GLIBCXX_USE_C99_MATH_TR1 return std::hypot(__x, __y); #else return std::sqrt(__x * __x + __y * __y); #endif } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typename std::normal_distribution::param_type __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma()); result_type __x = this->_M_ndx(__px, __urng); result_type __y = this->_M_ndy(__py, __urng); #if _GLIBCXX_USE_C99_MATH_TR1 return std::hypot(__x, __y); #else return std::sqrt(__x * __x + __y * __y); #endif } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Rice distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const rice_distribution& __d1, const rice_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_ndx == __d2._M_ndx && __d1._M_ndy == __d2._M_ndy); } /** * @brief Inserts a %rice_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %rice_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const rice_distribution<_RealType1>&); /** * @brief Extracts a %rice_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %rice_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, rice_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution _M_ndx; std::normal_distribution _M_ndy; }; /** * @brief Return true if two Rice distributions are not equal. */ template inline bool operator!=(const rice_distribution<_RealType1>& __d1, const rice_distribution<_RealType1>& __d2) { return !(__d1 == __d2); } /** * @brief A Nakagami continuous distribution for random numbers. * * The formula for the Nakagami probability density function is * @f[ * p(x|\mu,\omega) = \frac{2\mu^\mu}{\Gamma(\mu)\omega^\mu} * x^{2\mu-1}e^{-\mu x / \omega} * @f] * where @f$\Gamma(z)@f$ is the gamma function and @f$\mu >= 0.5@f$ * and @f$\omega > 0@f$. */ template class nakagami_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef nakagami_distribution distribution_type; param_type(result_type __mu_val = result_type(1), result_type __omega_val = result_type(1)) : _M_mu(__mu_val), _M_omega(__omega_val) { __glibcxx_assert(_M_mu >= result_type(0.5L)); __glibcxx_assert(_M_omega > result_type(0)); } result_type mu() const { return _M_mu; } result_type omega() const { return _M_omega; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_mu == __p2._M_mu && __p1._M_omega == __p2._M_omega; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_mu; result_type _M_omega; }; /** * @brief Constructors. */ explicit nakagami_distribution(result_type __mu_val = result_type(1), result_type __omega_val = result_type(1)) : _M_param(__mu_val, __omega_val), _M_gd(__mu_val, __omega_val / __mu_val) { } explicit nakagami_distribution(const param_type& __p) : _M_param(__p), _M_gd(__p.mu(), __p.omega() / __p.mu()) { } /** * @brief Resets the distribution state. */ void reset() { _M_gd.reset(); } /** * @brief Return the parameters of the distribution. */ result_type mu() const { return _M_param.mu(); } result_type omega() const { return _M_param.omega(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return std::sqrt(this->_M_gd(__urng)); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typename std::gamma_distribution::param_type __pg(__p.mu(), __p.omega() / __p.mu()); return std::sqrt(this->_M_gd(__pg, __urng)); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Nakagami distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const nakagami_distribution& __d1, const nakagami_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd); } /** * @brief Inserts a %nakagami_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %nakagami_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const nakagami_distribution<_RealType1>&); /** * @brief Extracts a %nakagami_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %nakagami_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, nakagami_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::gamma_distribution _M_gd; }; /** * @brief Return true if two Nakagami distributions are not equal. */ template inline bool operator!=(const nakagami_distribution<_RealType>& __d1, const nakagami_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A Pareto continuous distribution for random numbers. * * The formula for the Pareto cumulative probability function is * @f[ * P(x|\alpha,\mu) = 1 - \left(\frac{\mu}{x}\right)^\alpha * @f] * The formula for the Pareto probability density function is * @f[ * p(x|\alpha,\mu) = \frac{\alpha + 1}{\mu} * \left(\frac{\mu}{x}\right)^{\alpha + 1} * @f] * where @f$x >= \mu@f$ and @f$\mu > 0@f$, @f$\alpha > 0@f$. * * * * * * *
Distribution Statistics
Mean@f$\alpha \mu / (\alpha - 1)@f$ * for @f$\alpha > 1@f$
Variance@f$\alpha \mu^2 / [(\alpha - 1)^2(\alpha - 2)]@f$ * for @f$\alpha > 2@f$
Range@f$[\mu, \infty)@f$
*/ template class pareto_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef pareto_distribution distribution_type; param_type(result_type __alpha_val = result_type(1), result_type __mu_val = result_type(1)) : _M_alpha(__alpha_val), _M_mu(__mu_val) { __glibcxx_assert(_M_alpha > result_type(0)); __glibcxx_assert(_M_mu > result_type(0)); } result_type alpha() const { return _M_alpha; } result_type mu() const { return _M_mu; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_alpha == __p2._M_alpha && __p1._M_mu == __p2._M_mu; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_alpha; result_type _M_mu; }; /** * @brief Constructors. */ explicit pareto_distribution(result_type __alpha_val = result_type(1), result_type __mu_val = result_type(1)) : _M_param(__alpha_val, __mu_val), _M_ud() { } explicit pareto_distribution(const param_type& __p) : _M_param(__p), _M_ud() { } /** * @brief Resets the distribution state. */ void reset() { _M_ud.reset(); } /** * @brief Return the parameters of the distribution. */ result_type alpha() const { return _M_param.alpha(); } result_type mu() const { return _M_param.mu(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return this->mu(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->mu() * std::pow(this->_M_ud(__urng), -result_type(1) / this->alpha()); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { return __p.mu() * std::pow(this->_M_ud(__urng), -result_type(1) / __p.alpha()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Pareto distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const pareto_distribution& __d1, const pareto_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_ud == __d2._M_ud); } /** * @brief Inserts a %pareto_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %pareto_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const pareto_distribution<_RealType1>&); /** * @brief Extracts a %pareto_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %pareto_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, pareto_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::uniform_real_distribution _M_ud; }; /** * @brief Return true if two Pareto distributions are not equal. */ template inline bool operator!=(const pareto_distribution<_RealType>& __d1, const pareto_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A K continuous distribution for random numbers. * * The formula for the K probability density function is * @f[ * p(x|\lambda, \mu, \nu) = \frac{2}{x} * \left(\frac{\lambda\nu x}{\mu}\right)^{\frac{\lambda + \nu}{2}} * \frac{1}{\Gamma(\lambda)\Gamma(\nu)} * K_{\nu - \lambda}\left(2\sqrt{\frac{\lambda\nu x}{\mu}}\right) * @f] * where @f$I_0(z)@f$ is the modified Bessel function of the second kind * of order @f$\nu - \lambda@f$ and @f$\lambda > 0@f$, @f$\mu > 0@f$ * and @f$\nu > 0@f$. * * * * * * *
Distribution Statistics
Mean@f$\mu@f$
Variance@f$\mu^2\frac{\lambda + \nu + 1}{\lambda\nu}@f$
Range@f$[0, \infty)@f$
*/ template class k_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef k_distribution distribution_type; param_type(result_type __lambda_val = result_type(1), result_type __mu_val = result_type(1), result_type __nu_val = result_type(1)) : _M_lambda(__lambda_val), _M_mu(__mu_val), _M_nu(__nu_val) { __glibcxx_assert(_M_lambda > result_type(0)); __glibcxx_assert(_M_mu > result_type(0)); __glibcxx_assert(_M_nu > result_type(0)); } result_type lambda() const { return _M_lambda; } result_type mu() const { return _M_mu; } result_type nu() const { return _M_nu; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_lambda == __p2._M_lambda && __p1._M_mu == __p2._M_mu && __p1._M_nu == __p2._M_nu; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_lambda; result_type _M_mu; result_type _M_nu; }; /** * @brief Constructors. */ explicit k_distribution(result_type __lambda_val = result_type(1), result_type __mu_val = result_type(1), result_type __nu_val = result_type(1)) : _M_param(__lambda_val, __mu_val, __nu_val), _M_gd1(__lambda_val, result_type(1) / __lambda_val), _M_gd2(__nu_val, __mu_val / __nu_val) { } explicit k_distribution(const param_type& __p) : _M_param(__p), _M_gd1(__p.lambda(), result_type(1) / __p.lambda()), _M_gd2(__p.nu(), __p.mu() / __p.nu()) { } /** * @brief Resets the distribution state. */ void reset() { _M_gd1.reset(); _M_gd2.reset(); } /** * @brief Return the parameters of the distribution. */ result_type lambda() const { return _M_param.lambda(); } result_type mu() const { return _M_param.mu(); } result_type nu() const { return _M_param.nu(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator&); template result_type operator()(_UniformRandomNumberGenerator&, const param_type&); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two K distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const k_distribution& __d1, const k_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_gd1 == __d2._M_gd1 && __d1._M_gd2 == __d2._M_gd2); } /** * @brief Inserts a %k_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %k_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const k_distribution<_RealType1>&); /** * @brief Extracts a %k_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %k_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, k_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::gamma_distribution _M_gd1; std::gamma_distribution _M_gd2; }; /** * @brief Return true if two K distributions are not equal. */ template inline bool operator!=(const k_distribution<_RealType>& __d1, const k_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief An arcsine continuous distribution for random numbers. * * The formula for the arcsine probability density function is * @f[ * p(x|a,b) = \frac{1}{\pi \sqrt{(x - a)(b - x)}} * @f] * where @f$x >= a@f$ and @f$x <= b@f$. * * * * * * *
Distribution Statistics
Mean@f$ (a + b) / 2 @f$
Variance@f$ (b - a)^2 / 8 @f$
Range@f$[a, b]@f$
*/ template class arcsine_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef arcsine_distribution distribution_type; param_type(result_type __a = result_type(0), result_type __b = result_type(1)) : _M_a(__a), _M_b(__b) { __glibcxx_assert(_M_a <= _M_b); } result_type a() const { return _M_a; } result_type b() const { return _M_b; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_a; result_type _M_b; }; /** * @brief Constructors. */ explicit arcsine_distribution(result_type __a = result_type(0), result_type __b = result_type(1)) : _M_param(__a, __b), _M_ud(-1.5707963267948966192313216916397514L, +1.5707963267948966192313216916397514L) { } explicit arcsine_distribution(const param_type& __p) : _M_param(__p), _M_ud(-1.5707963267948966192313216916397514L, +1.5707963267948966192313216916397514L) { } /** * @brief Resets the distribution state. */ void reset() { _M_ud.reset(); } /** * @brief Return the parameters of the distribution. */ result_type a() const { return _M_param.a(); } result_type b() const { return _M_param.b(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return this->a(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return this->b(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { result_type __x = std::sin(this->_M_ud(__urng)); return (__x * (this->b() - this->a()) + this->a() + this->b()) / result_type(2); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { result_type __x = std::sin(this->_M_ud(__urng)); return (__x * (__p.b() - __p.a()) + __p.a() + __p.b()) / result_type(2); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two arcsine distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const arcsine_distribution& __d1, const arcsine_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_ud == __d2._M_ud); } /** * @brief Inserts a %arcsine_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %arcsine_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const arcsine_distribution<_RealType1>&); /** * @brief Extracts a %arcsine_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %arcsine_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, arcsine_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::uniform_real_distribution _M_ud; }; /** * @brief Return true if two arcsine distributions are not equal. */ template inline bool operator!=(const arcsine_distribution<_RealType>& __d1, const arcsine_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A Hoyt continuous distribution for random numbers. * * The formula for the Hoyt probability density function is * @f[ * p(x|q,\omega) = \frac{(1 + q^2)x}{q\omega} * \exp\left(-\frac{(1 + q^2)^2 x^2}{4 q^2 \omega}\right) * I_0\left(\frac{(1 - q^4) x^2}{4 q^2 \omega}\right) * @f] * where @f$I_0(z)@f$ is the modified Bessel function of the first kind * of order 0 and @f$0 < q < 1@f$. * * * * * * *
Distribution Statistics
Mean@f$ \sqrt{\frac{2}{\pi}} \sqrt{\frac{\omega}{1 + q^2}} * E(1 - q^2) @f$
Variance@f$ \omega \left(1 - \frac{2E^2(1 - q^2)} * {\pi (1 + q^2)}\right) @f$
Range@f$[0, \infty)@f$
* where @f$E(x)@f$ is the elliptic function of the second kind. */ template class hoyt_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef hoyt_distribution distribution_type; param_type(result_type __q = result_type(0.5L), result_type __omega = result_type(1)) : _M_q(__q), _M_omega(__omega) { __glibcxx_assert(_M_q > result_type(0)); __glibcxx_assert(_M_q < result_type(1)); } result_type q() const { return _M_q; } result_type omega() const { return _M_omega; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_q == __p2._M_q && __p1._M_omega == __p2._M_omega; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_q; result_type _M_omega; }; /** * @brief Constructors. */ explicit hoyt_distribution(result_type __q = result_type(0.5L), result_type __omega = result_type(1)) : _M_param(__q, __omega), _M_ad(result_type(0.5L) * (result_type(1) + __q * __q), result_type(0.5L) * (result_type(1) + __q * __q) / (__q * __q)), _M_ed(result_type(1)) { } explicit hoyt_distribution(const param_type& __p) : _M_param(__p), _M_ad(result_type(0.5L) * (result_type(1) + __p.q() * __p.q()), result_type(0.5L) * (result_type(1) + __p.q() * __p.q()) / (__p.q() * __p.q())), _M_ed(result_type(1)) { } /** * @brief Resets the distribution state. */ void reset() { _M_ad.reset(); _M_ed.reset(); } /** * @brief Return the parameters of the distribution. */ result_type q() const { return _M_param.q(); } result_type omega() const { return _M_param.omega(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng); template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Hoyt distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const hoyt_distribution& __d1, const hoyt_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_ad == __d2._M_ad && __d1._M_ed == __d2._M_ed); } /** * @brief Inserts a %hoyt_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %hoyt_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const hoyt_distribution<_RealType1>&); /** * @brief Extracts a %hoyt_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %hoyt_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, hoyt_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; __gnu_cxx::arcsine_distribution _M_ad; std::exponential_distribution _M_ed; }; /** * @brief Return true if two Hoyt distributions are not equal. */ template inline bool operator!=(const hoyt_distribution<_RealType>& __d1, const hoyt_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A triangular distribution for random numbers. * * The formula for the triangular probability density function is * @f[ * / 0 for x < a * p(x|a,b,c) = | \frac{2(x-a)}{(c-a)(b-a)} for a <= x <= b * | \frac{2(c-x)}{(c-a)(c-b)} for b < x <= c * \ 0 for c < x * @f] * * * * * * *
Distribution Statistics
Mean@f$ \frac{a+b+c}{2} @f$
Variance@f$ \frac{a^2+b^2+c^2-ab-ac-bc} * {18}@f$
Range@f$[a, c]@f$
*/ template class triangular_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { friend class triangular_distribution<_RealType>; explicit param_type(_RealType __a = _RealType(0), _RealType __b = _RealType(0.5), _RealType __c = _RealType(1)) : _M_a(__a), _M_b(__b), _M_c(__c) { __glibcxx_assert(_M_a <= _M_b); __glibcxx_assert(_M_b <= _M_c); __glibcxx_assert(_M_a < _M_c); _M_r_ab = (_M_b - _M_a) / (_M_c - _M_a); _M_f_ab_ac = (_M_b - _M_a) * (_M_c - _M_a); _M_f_bc_ac = (_M_c - _M_b) * (_M_c - _M_a); } _RealType a() const { return _M_a; } _RealType b() const { return _M_b; } _RealType c() const { return _M_c; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return (__p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b && __p1._M_c == __p2._M_c); } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_a; _RealType _M_b; _RealType _M_c; _RealType _M_r_ab; _RealType _M_f_ab_ac; _RealType _M_f_bc_ac; }; /** * @brief Constructs a triangle distribution with parameters * @f$ a @f$, @f$ b @f$ and @f$ c @f$. */ explicit triangular_distribution(result_type __a = result_type(0), result_type __b = result_type(0.5), result_type __c = result_type(1)) : _M_param(__a, __b, __c) { } explicit triangular_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the @f$ a @f$ of the distribution. */ result_type a() const { return _M_param.a(); } /** * @brief Returns the @f$ b @f$ of the distribution. */ result_type b() const { return _M_param.b(); } /** * @brief Returns the @f$ c @f$ of the distribution. */ result_type c() const { return _M_param.c(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return _M_param._M_a; } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return _M_param._M_c; } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __rnd = __aurng(); if (__rnd <= __p._M_r_ab) return __p.a() + std::sqrt(__rnd * __p._M_f_ab_ac); else return __p.c() - std::sqrt((result_type(1) - __rnd) * __p._M_f_bc_ac); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two triangle distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const triangular_distribution& __d1, const triangular_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %triangular_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %triangular_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::triangular_distribution<_RealType1>& __x); /** * @brief Extracts a %triangular_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %triangular_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::triangular_distribution<_RealType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two triangle distributions are different. */ template inline bool operator!=(const __gnu_cxx::triangular_distribution<_RealType>& __d1, const __gnu_cxx::triangular_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A von Mises distribution for random numbers. * * The formula for the von Mises probability density function is * @f[ * p(x|\mu,\kappa) = \frac{e^{\kappa \cos(x-\mu)}} * {2\pi I_0(\kappa)} * @f] * * The generating functions use the method according to: * * D. J. Best and N. I. Fisher, 1979. "Efficient Simulation of the * von Mises Distribution", Journal of the Royal Statistical Society. * Series C (Applied Statistics), Vol. 28, No. 2, pp. 152-157. * * * * * * *
Distribution Statistics
Mean@f$ \mu @f$
Variance@f$ 1-I_1(\kappa)/I_0(\kappa) @f$
Range@f$[-\pi, \pi]@f$
*/ template class von_mises_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { friend class von_mises_distribution<_RealType>; explicit param_type(_RealType __mu = _RealType(0), _RealType __kappa = _RealType(1)) : _M_mu(__mu), _M_kappa(__kappa) { const _RealType __pi = __gnu_cxx::__math_constants<_RealType>::__pi; __glibcxx_assert(_M_mu >= -__pi && _M_mu <= __pi); __glibcxx_assert(_M_kappa >= _RealType(0)); auto __tau = std::sqrt(_RealType(4) * _M_kappa * _M_kappa + _RealType(1)) + _RealType(1); auto __rho = ((__tau - std::sqrt(_RealType(2) * __tau)) / (_RealType(2) * _M_kappa)); _M_r = (_RealType(1) + __rho * __rho) / (_RealType(2) * __rho); } _RealType mu() const { return _M_mu; } _RealType kappa() const { return _M_kappa; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_mu == __p2._M_mu && __p1._M_kappa == __p2._M_kappa; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_mu; _RealType _M_kappa; _RealType _M_r; }; /** * @brief Constructs a von Mises distribution with parameters * @f$\mu@f$ and @f$\kappa@f$. */ explicit von_mises_distribution(result_type __mu = result_type(0), result_type __kappa = result_type(1)) : _M_param(__mu, __kappa) { } explicit von_mises_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the @f$ \mu @f$ of the distribution. */ result_type mu() const { return _M_param.mu(); } /** * @brief Returns the @f$ \kappa @f$ of the distribution. */ result_type kappa() const { return _M_param.kappa(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return -__gnu_cxx::__math_constants::__pi; } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return __gnu_cxx::__math_constants::__pi; } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two von Mises distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const von_mises_distribution& __d1, const von_mises_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %von_mises_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %von_mises_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::von_mises_distribution<_RealType1>& __x); /** * @brief Extracts a %von_mises_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %von_mises_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::von_mises_distribution<_RealType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two von Mises distributions are different. */ template inline bool operator!=(const __gnu_cxx::von_mises_distribution<_RealType>& __d1, const __gnu_cxx::von_mises_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A discrete hypergeometric random number distribution. * * The hypergeometric distribution is a discrete probability distribution * that describes the probability of @p k successes in @p n draws @a without * replacement from a finite population of size @p N containing exactly @p K * successes. * * The formula for the hypergeometric probability density function is * @f[ * p(k|N,K,n) = \frac{\binom{K}{k} \binom{N-K}{n-k}}{\binom{N}{n}} * @f] * where @f$N@f$ is the total population of the distribution, * @f$K@f$ is the total population of the distribution. * * * * * * *
Distribution Statistics
Mean@f$ n\frac{K}{N} @f$
Variance@f$ n\frac{K}{N}\frac{N-K}{N}\frac{N-n}{N-1} * @f$
Range@f$[max(0, n+K-N), min(K, n)]@f$
*/ template class hypergeometric_distribution { static_assert(std::is_unsigned<_UIntType>::value, "template argument " "substituting _UIntType not an unsigned integral type"); public: /** The type of the range of the distribution. */ typedef _UIntType result_type; /** Parameter type. */ struct param_type { typedef hypergeometric_distribution<_UIntType> distribution_type; friend class hypergeometric_distribution<_UIntType>; explicit param_type(result_type __N = 10, result_type __K = 5, result_type __n = 1) : _M_N{__N}, _M_K{__K}, _M_n{__n} { __glibcxx_assert(_M_N >= _M_K); __glibcxx_assert(_M_N >= _M_n); } result_type total_size() const { return _M_N; } result_type successful_size() const { return _M_K; } result_type unsuccessful_size() const { return _M_N - _M_K; } result_type total_draws() const { return _M_n; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return (__p1._M_N == __p2._M_N) && (__p1._M_K == __p2._M_K) && (__p1._M_n == __p2._M_n); } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: result_type _M_N; result_type _M_K; result_type _M_n; }; // constructors and member function explicit hypergeometric_distribution(result_type __N = 10, result_type __K = 5, result_type __n = 1) : _M_param{__N, __K, __n} { } explicit hypergeometric_distribution(const param_type& __p) : _M_param{__p} { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the distribution parameter @p N, * the total number of items. */ result_type total_size() const { return this->_M_param.total_size(); } /** * @brief Returns the distribution parameter @p K, * the total number of successful items. */ result_type successful_size() const { return this->_M_param.successful_size(); } /** * @brief Returns the total number of unsuccessful items @f$ N - K @f$. */ result_type unsuccessful_size() const { return this->_M_param.unsuccessful_size(); } /** * @brief Returns the distribution parameter @p n, * the total number of draws. */ result_type total_draws() const { return this->_M_param.total_draws(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return this->_M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { this->_M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { using _IntType = typename std::make_signed::type; return static_cast(std::max(static_cast<_IntType>(0), static_cast<_IntType>(this->total_draws() - this->unsuccessful_size()))); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::min(this->successful_size(), this->total_draws()); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, this->_M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->_M_param); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two hypergeometric distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const hypergeometric_distribution& __d1, const hypergeometric_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %hypergeometric_distribution random number * distribution @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %hypergeometric_distribution random number * distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::hypergeometric_distribution<_UIntType1>& __x); /** * @brief Extracts a %hypergeometric_distribution random number * distribution @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %hypergeometric_distribution random number generator * distribution. * * @returns The input stream with @p __x extracted or in an error * state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::hypergeometric_distribution<_UIntType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two hypergeometric distributions are different. */ template inline bool operator!=(const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d1, const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2) { return !(__d1 == __d2); } /** * @brief A logistic continuous distribution for random numbers. * * The formula for the logistic probability density function is * @f[ * p(x|\a,\b) = \frac{e^{(x - a)/b}}{b[1 + e^{(x - a)/b}]^2} * @f] * where @f$b > 0@f$. * * The formula for the logistic probability function is * @f[ * cdf(x|\a,\b) = \frac{e^{(x - a)/b}}{1 + e^{(x - a)/b}} * @f] * where @f$b > 0@f$. * * * * * * *
Distribution Statistics
Mean@f$a@f$
Variance@f$b^2\pi^2/3@f$
Range@f$[0, \infty)@f$
*/ template class logistic_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef logistic_distribution distribution_type; param_type(result_type __a = result_type(0), result_type __b = result_type(1)) : _M_a(__a), _M_b(__b) { __glibcxx_assert(_M_b > result_type(0)); } result_type a() const { return _M_a; } result_type b() const { return _M_b; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_a; result_type _M_b; }; /** * @brief Constructors. */ explicit logistic_distribution(result_type __a = result_type(0), result_type __b = result_type(1)) : _M_param(__a, __b) { } explicit logistic_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Return the parameters of the distribution. */ result_type a() const { return _M_param.a(); } result_type b() const { return _M_param.b(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return -std::numeric_limits::max(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits::max(); } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, this->_M_param); } template result_type operator()(_UniformRandomNumberGenerator&, const param_type&); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two logistic distributions have * the same parameters and the sequences that would * be generated are equal. */ template friend bool operator==(const logistic_distribution<_RealType1>& __d1, const logistic_distribution<_RealType1>& __d2) { return __d1.param() == __d2.param(); } /** * @brief Inserts a %logistic_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %logistic_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const logistic_distribution<_RealType1>&); /** * @brief Extracts a %logistic_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %logistic_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, logistic_distribution<_RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two logistic distributions are not equal. */ template inline bool operator!=(const logistic_distribution<_RealType1>& __d1, const logistic_distribution<_RealType1>& __d2) { return !(__d1 == __d2); } /** * @brief A distribution for random coordinates on a unit sphere. * * The method used in the generation function is attributed by Donald Knuth * to G. W. Brown, Modern Mathematics for the Engineer (1956). */ template class uniform_on_sphere_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); static_assert(_Dimen != 0, "dimension is zero"); public: /** The type of the range of the distribution. */ typedef std::array<_RealType, _Dimen> result_type; /** Parameter type. */ struct param_type { explicit param_type() { } friend bool operator==(const param_type&, const param_type&) { return true; } friend bool operator!=(const param_type&, const param_type&) { return false; } }; /** * @brief Constructs a uniform on sphere distribution. */ explicit uniform_on_sphere_distribution() : _M_param(), _M_nd() { } explicit uniform_on_sphere_distribution(const param_type& __p) : _M_param(__p), _M_nd() { } /** * @brief Resets the distribution state. */ void reset() { _M_nd.reset(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. * This function makes no sense for this distribution. */ result_type min() const { result_type __res; __res.fill(0); return __res; } /** * @brief Returns the least upper bound value of the distribution. * This function makes no sense for this distribution. */ result_type max() const { result_type __res; __res.fill(0); return __res; } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two uniform on sphere distributions have * the same parameters and the sequences that would be * generated are equal. */ friend bool operator==(const uniform_on_sphere_distribution& __d1, const uniform_on_sphere_distribution& __d2) { return __d1._M_nd == __d2._M_nd; } /** * @brief Inserts a %uniform_on_sphere_distribution random number * distribution @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %uniform_on_sphere_distribution random number * distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::uniform_on_sphere_distribution<_Dimen1, _RealType1>& __x); /** * @brief Extracts a %uniform_on_sphere_distribution random number * distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %uniform_on_sphere_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::uniform_on_sphere_distribution<_Dimen1, _RealType1>& __x); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution<_RealType> _M_nd; }; /** * @brief Return true if two uniform on sphere distributions are different. */ template inline bool operator!=(const __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>& __d1, const __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A distribution for random coordinates inside a unit sphere. */ template class uniform_inside_sphere_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); static_assert(_Dimen != 0, "dimension is zero"); public: /** The type of the range of the distribution. */ using result_type = std::array<_RealType, _Dimen>; /** Parameter type. */ struct param_type { using distribution_type = uniform_inside_sphere_distribution<_Dimen, _RealType>; friend class uniform_inside_sphere_distribution<_Dimen, _RealType>; explicit param_type(_RealType __radius = _RealType(1)) : _M_radius(__radius) { __glibcxx_assert(_M_radius > _RealType(0)); } _RealType radius() const { return _M_radius; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_radius == __p2._M_radius; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_radius; }; /** * @brief Constructors. */ explicit uniform_inside_sphere_distribution(_RealType __radius = _RealType(1)) : _M_param(__radius), _M_uosd() { } explicit uniform_inside_sphere_distribution(const param_type& __p) : _M_param(__p), _M_uosd() { } /** * @brief Resets the distribution state. */ void reset() { _M_uosd.reset(); } /** * @brief Returns the @f$radius@f$ of the distribution. */ _RealType radius() const { return _M_param.radius(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. * This function makes no sense for this distribution. */ result_type min() const { result_type __res; __res.fill(0); return __res; } /** * @brief Returns the least upper bound value of the distribution. * This function makes no sense for this distribution. */ result_type max() const { result_type __res; __res.fill(0); return __res; } /** * @brief Generating functions. */ template result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two uniform on sphere distributions have * the same parameters and the sequences that would be * generated are equal. */ friend bool operator==(const uniform_inside_sphere_distribution& __d1, const uniform_inside_sphere_distribution& __d2) { return __d1._M_param == __d2._M_param && __d1._M_uosd == __d2._M_uosd; } /** * @brief Inserts a %uniform_inside_sphere_distribution random number * distribution @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %uniform_inside_sphere_distribution random number * distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1, _RealType1>& ); /** * @brief Extracts a %uniform_inside_sphere_distribution random number * distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %uniform_inside_sphere_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1, _RealType1>&); private: template void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; uniform_on_sphere_distribution<_Dimen, _RealType> _M_uosd; }; /** * @brief Return true if two uniform on sphere distributions are different. */ template inline bool operator!=(const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, _RealType>& __d1, const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, _RealType>& __d2) { return !(__d1 == __d2); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx #include #include #endif // _GLIBCXX_USE_C99_STDINT_TR1 && UINT32_C #endif // C++11 #endif // _EXT_RANDOM 8/ext/pb_ds/tree_policy.hpp000064400000012711152526447520011647 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tree_policy.hpp * Contains tree-related policies. */ #ifndef PB_DS_TREE_POLICY_HPP #define PB_DS_TREE_POLICY_HPP #include #include #include #include namespace __gnu_pbds { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ tree_order_statistics_node_update #define PB_DS_BRANCH_POLICY_BASE \ detail::branch_policy /// Functor updating ranks of entrees. template class tree_order_statistics_node_update : private PB_DS_BRANCH_POLICY_BASE { private: typedef PB_DS_BRANCH_POLICY_BASE base_type; public: typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef typename base_type::key_type key_type; typedef typename base_type::key_const_reference key_const_reference; typedef size_type metadata_type; typedef Node_CItr node_const_iterator; typedef Node_Itr node_iterator; typedef typename node_const_iterator::value_type const_iterator; typedef typename node_iterator::value_type iterator; /// Finds an entry by __order. Returns a const_iterator to the /// entry with the __order order, or a const_iterator to the /// container object's end if order is at least the size of the /// container object. inline const_iterator find_by_order(size_type) const; /// Finds an entry by __order. Returns an iterator to the entry /// with the __order order, or an iterator to the container /// object's end if order is at least the size of the container /// object. inline iterator find_by_order(size_type); /// Returns the order of a key within a sequence. For exapmle, if /// r_key is the smallest key, this method will return 0; if r_key /// is a key between the smallest and next key, this method will /// return 1; if r_key is a key larger than the largest key, this /// method will return the size of r_c. inline size_type order_of_key(key_const_reference) const; private: /// Const reference to the container's value-type. typedef typename base_type::const_reference const_reference; /// Const pointer to the container's value-type. typedef typename base_type::const_pointer const_pointer; typedef typename _Alloc::template rebind::other __rebind_m; /// Const metadata reference. typedef typename __rebind_m::const_reference metadata_const_reference; /// Metadata reference. typedef typename __rebind_m::reference metadata_reference; /// Returns the node_const_iterator associated with the tree's root node. virtual node_const_iterator node_begin() const = 0; /// Returns the node_iterator associated with the tree's root node. virtual node_iterator node_begin() = 0; /// Returns the node_const_iterator associated with a just-after leaf node. virtual node_const_iterator node_end() const = 0; /// Returns the node_iterator associated with a just-after leaf node. virtual node_iterator node_end() = 0; /// Access to the cmp_fn object. virtual cmp_fn& get_cmp_fn() = 0; protected: /// Updates the rank of a node through a node_iterator node_it; /// end_nd_it is the end node iterator. inline void operator()(node_iterator, node_const_iterator) const; virtual ~tree_order_statistics_node_update(); }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_BRANCH_POLICY_BASE } // namespace __gnu_pbds #endif 8/ext/pb_ds/list_update_policy.hpp000064400000010420152526447520013220 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_policy.hpp * Contains policies for list update containers. */ #ifndef PB_DS_LU_POLICY_HPP #define PB_DS_LU_POLICY_HPP #include #include #include #include namespace __gnu_pbds { /** * A list-update policy that unconditionally moves elements to the * front of the list. A null type means that each link in a * list-based container does not actually need metadata. */ template > class lu_move_to_front_policy { public: typedef _Alloc allocator_type; /// Metadata on which this functor operates. typedef null_type metadata_type; private: typedef typename _Alloc::template rebind __rebind_m; public: /// Reference to metadata on which this functor operates. typedef typename __rebind_m::other::reference metadata_reference; /// Creates a metadata object. metadata_type operator()() const { return s_metadata; } /// Decides whether a metadata object should be moved to the front /// of the list. inline bool operator()(metadata_reference r_metadata) const { return true; } private: static null_type s_metadata; }; /** * A list-update policy that moves elements to the front of the * list based on the counter algorithm. */ template > class lu_counter_policy : private detail::lu_counter_policy_base { public: typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; enum { /// When some element is accessed this number of times, it /// will be moved to the front of the list. max_count = Max_Count }; /// Metadata on which this functor operates. typedef detail::lu_counter_metadata metadata_type; private: typedef detail::lu_counter_policy_base base_type; typedef typename _Alloc::template rebind __rebind_m; public: /// Reference to metadata on which this functor operates. typedef typename __rebind_m::other::reference metadata_reference; /// Creates a metadata object. metadata_type operator()() const { return base_type::operator()(max_count); } /// Decides whether a metadata object should be moved to the front /// of the list. bool operator()(metadata_reference r_data) const { return base_type::operator()(r_data, max_count); } }; } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp000064400000004056152526447520020037 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file direct_mod_range_hashing_imp.hpp * Contains a range-hashing policy implementation */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { mod_based_base::swap(other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type n) { mod_based_base::notify_resized(n); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(size_type hash) const { return mod_based_base::range_hash(hash); } 8/ext/pb_ds/detail/hash_fn/probe_fn_base.hpp000064400000003731152526447520014767 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file probe_fn_base.hpp * Contains a probe policy base. */ #ifndef PB_DS_PROBE_FN_BASE_HPP #define PB_DS_PROBE_FN_BASE_HPP #include namespace __gnu_pbds { namespace detail { /// Probe functor base. template class probe_fn_base { protected: ~probe_fn_base() { } }; } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp000064400000024573152526447520015140 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ranged_hash_fn.hpp * Contains a unified ranged hash functor, allowing the hash tables * to deal with a single class for ranged hashing. */ #ifndef PB_DS_RANGED_HASH_FN_HPP #define PB_DS_RANGED_HASH_FN_HPP #include #include namespace __gnu_pbds { namespace detail { /// Primary template. template class ranged_hash_fn; #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ ranged_hash_fn /** * Specialization 1 * The client supplies a hash function and a ranged hash function, * and requests that hash values not be stored. **/ template class ranged_hash_fn< Key, Hash_Fn, _Alloc, Comb_Hash_Fn, false> : public Hash_Fn, public Comb_Hash_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Hash_Fn hash_fn_base; typedef Comb_Hash_Fn comb_hash_fn_base; typedef typename _Alloc::template rebind< Key>::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_hash_fn(size_type); ranged_hash_fn(size_type, const Hash_Fn&); ranged_hash_fn(size_type, const Hash_Fn&, const Comb_Hash_Fn&); void swap(PB_DS_CLASS_C_DEC&); void notify_resized(size_type); inline size_type operator()(key_const_reference) const; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn) : Hash_Fn(r_hash_fn) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn) : Hash_Fn(r_hash_fn), Comb_Hash_Fn(r_comb_hash_fn) { comb_hash_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_hash_fn_base::swap(other); std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { comb_hash_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(key_const_reference r_key) const { return (comb_hash_fn_base::operator()(hash_fn_base::operator()(r_key)));} #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ ranged_hash_fn /** * Specialization 2 * The client supplies a hash function and a ranged hash function, * and requests that hash values be stored. **/ template class ranged_hash_fn : public Hash_Fn, public Comb_Hash_Fn { protected: typedef typename _Alloc::size_type size_type; typedef std::pair comp_hash; typedef Hash_Fn hash_fn_base; typedef Comb_Hash_Fn comb_hash_fn_base; typedef typename _Alloc::template rebind::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_hash_fn(size_type); ranged_hash_fn(size_type, const Hash_Fn&); ranged_hash_fn(size_type, const Hash_Fn&, const Comb_Hash_Fn&); void swap(PB_DS_CLASS_C_DEC&); void notify_resized(size_type); inline comp_hash operator()(key_const_reference) const; inline comp_hash operator()(key_const_reference, size_type) const; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn) : Hash_Fn(r_hash_fn) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn) : Hash_Fn(r_hash_fn), Comb_Hash_Fn(r_comb_hash_fn) { comb_hash_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_hash_fn_base::swap(other); std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { comb_hash_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::comp_hash PB_DS_CLASS_C_DEC:: operator()(key_const_reference r_key) const { const size_type hash = hash_fn_base::operator()(r_key); return std::make_pair(comb_hash_fn_base::operator()(hash), hash); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::comp_hash PB_DS_CLASS_C_DEC:: operator() #ifdef _GLIBCXX_DEBUG (key_const_reference r_key, size_type hash) const #else (key_const_reference /*r_key*/, size_type hash) const #endif { _GLIBCXX_DEBUG_ASSERT(hash == hash_fn_base::operator()(r_key)); return std::make_pair(comb_hash_fn_base::operator()(hash), hash); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ ranged_hash_fn /** * Specialization 3 * The client does not supply a hash function (by specifying * null_type as the Hash_Fn parameter), and requests that hash * values not be stored. **/ template class ranged_hash_fn : public Comb_Hash_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Comb_Hash_Fn comb_hash_fn_base; ranged_hash_fn(size_type); ranged_hash_fn(size_type, const Comb_Hash_Fn&); ranged_hash_fn(size_type, const null_type&, const Comb_Hash_Fn&); void swap(PB_DS_CLASS_C_DEC&); }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn) : Comb_Hash_Fn(r_comb_hash_fn) { } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const null_type& r_null_type, const Comb_Hash_Fn& r_comb_hash_fn) : Comb_Hash_Fn(r_comb_hash_fn) { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_hash_fn_base::swap(other); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ ranged_hash_fn /** * Specialization 4 * The client does not supply a hash function (by specifying * null_type as the Hash_Fn parameter), and requests that hash * values be stored. **/ template class ranged_hash_fn : public Comb_Hash_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Comb_Hash_Fn comb_hash_fn_base; ranged_hash_fn(size_type); ranged_hash_fn(size_type, const Comb_Hash_Fn&); ranged_hash_fn(size_type, const null_type&, const Comb_Hash_Fn&); void swap(PB_DS_CLASS_C_DEC&); }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn) : Comb_Hash_Fn(r_comb_hash_fn) { } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const null_type& r_null_type, const Comb_Hash_Fn& r_comb_hash_fn) : Comb_Hash_Fn(r_comb_hash_fn) { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_hash_fn_base::swap(other); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp000064400000004070152526447520020207 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file direct_mask_range_hashing_imp.hpp * Contains a range-hashing policy implementation */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { mask_based_base::swap(other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { mask_based_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(size_type hash) const { return mask_based_base::range_hash(hash); } 8/ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp000064400000003571152526447520016176 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file linear_probe_fn_imp.hpp * Contains a probe policy implementation */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(size_type i) const { return (i); } 8/ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp000064400000003600152526447520016672 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file quadratic_probe_fn_imp.hpp * Contains a probe policy implementation */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(size_type i) const { return (i* i); } 8/ext/pb_ds/detail/hash_fn/sample_ranged_hash_fn.hpp000064400000004645152526447520016477 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_ranged_hash_fn.hpp * Contains a ranged hash policy. */ #ifndef PB_DS_SAMPLE_RANGED_HASH_FN_HPP #define PB_DS_SAMPLE_RANGED_HASH_FN_HPP namespace __gnu_pbds { /// A sample ranged-hash functor. class sample_ranged_hash_fn { public: typedef std::size_t size_type; /// Default constructor. sample_ranged_hash_fn(); /// Copy constructor. sample_ranged_hash_fn(const sample_ranged_hash_fn&); /// Swaps content. inline void swap(sample_ranged_hash_fn&); protected: /// Notifies the policy object that the container's __size has /// changed to size. void notify_resized(size_type); /// Transforms key_const_reference into a position within the table. inline size_type operator()(key_const_reference) const; }; } #endif // #ifndef PB_DS_SAMPLE_RANGED_HASH_FN_HPP 8/ext/pb_ds/detail/hash_fn/ranged_probe_fn.hpp000064400000024304152526447520015314 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ranged_probe_fn.hpp * Contains a unified ranged probe functor, allowing the probe tables to deal with * a single class for ranged probeing. */ #ifndef PB_DS_RANGED_PROBE_FN_HPP #define PB_DS_RANGED_PROBE_FN_HPP #include #include namespace __gnu_pbds { namespace detail { /// Primary template. template class ranged_probe_fn; #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ ranged_probe_fn /** * Specialization 1 * The client supplies a probe function and a ranged probe * function, and requests that hash values not be stored. **/ template class ranged_probe_fn : public Hash_Fn, public Comb_Probe_Fn, public Probe_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Comb_Probe_Fn comb_probe_fn_base; typedef Hash_Fn hash_fn_base; typedef Probe_Fn probe_fn_base; typedef typename _Alloc::template rebind::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_probe_fn(size_type); ranged_probe_fn(size_type, const Hash_Fn&); ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&); ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&, const Probe_Fn&); void swap(PB_DS_CLASS_C_DEC&); void notify_resized(size_type); inline size_type operator()(key_const_reference) const; inline size_type operator()(key_const_reference, size_type, size_type) const; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size) { Comb_Probe_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn) : Hash_Fn(r_hash_fn) { Comb_Probe_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Probe_Fn& r_comb_probe_fn) : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Probe_Fn& r_comb_probe_fn, const Probe_Fn& r_probe_fn) : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn), Probe_Fn(r_probe_fn) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_probe_fn_base::swap(other); std::swap((Hash_Fn& )(*this), (Hash_Fn&)other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(key_const_reference r_key) const { return comb_probe_fn_base::operator()(hash_fn_base::operator()(r_key)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(key_const_reference, size_type hash, size_type i) const { return comb_probe_fn_base::operator()(hash + probe_fn_base::operator()(i)); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ ranged_probe_fn /** * Specialization 2- The client supplies a probe function and a ranged * probe function, and requests that hash values not be stored. **/ template class ranged_probe_fn : public Hash_Fn, public Comb_Probe_Fn, public Probe_Fn { protected: typedef typename _Alloc::size_type size_type; typedef std::pair comp_hash; typedef Comb_Probe_Fn comb_probe_fn_base; typedef Hash_Fn hash_fn_base; typedef Probe_Fn probe_fn_base; typedef typename _Alloc::template rebind::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_probe_fn(size_type); ranged_probe_fn(size_type, const Hash_Fn&); ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&); ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&, const Probe_Fn&); void swap(PB_DS_CLASS_C_DEC&); void notify_resized(size_type); inline comp_hash operator()(key_const_reference) const; inline size_type operator()(key_const_reference, size_type, size_type) const; inline size_type operator()(key_const_reference, size_type) const; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size) { Comb_Probe_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn) : Hash_Fn(r_hash_fn) { Comb_Probe_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Probe_Fn& r_comb_probe_fn) : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Probe_Fn& r_comb_probe_fn, const Probe_Fn& r_probe_fn) : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn), Probe_Fn(r_probe_fn) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_probe_fn_base::swap(other); std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::comp_hash PB_DS_CLASS_C_DEC:: operator()(key_const_reference r_key) const { const size_type hash = hash_fn_base::operator()(r_key); return std::make_pair(comb_probe_fn_base::operator()(hash), hash); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(key_const_reference, size_type hash, size_type i) const { return comb_probe_fn_base::operator()(hash + probe_fn_base::operator()(i)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator() #ifdef _GLIBCXX_DEBUG (key_const_reference r_key, size_type hash) const #else (key_const_reference /*r_key*/, size_type hash) const #endif { _GLIBCXX_DEBUG_ASSERT(hash == hash_fn_base::operator()(r_key)); return hash; } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC /** * Specialization 3 and 4 * The client does not supply a hash function or probe function, * and requests that hash values not be stored. **/ template class ranged_probe_fn : public Comb_Probe_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Comb_Probe_Fn comb_probe_fn_base; typedef typename _Alloc::template rebind::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_probe_fn(size_type size) { Comb_Probe_Fn::notify_resized(size); } ranged_probe_fn(size_type, const Comb_Probe_Fn& r_comb_probe_fn) : Comb_Probe_Fn(r_comb_probe_fn) { } ranged_probe_fn(size_type, const null_type&, const Comb_Probe_Fn& r_comb_probe_fn, const null_type&) : Comb_Probe_Fn(r_comb_probe_fn) { } void swap(ranged_probe_fn& other) { comb_probe_fn_base::swap(other); } }; } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/hash_fn/sample_range_hashing.hpp000064400000004667152526447520016352 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_range_hashing.hpp * Contains a range hashing policy. */ #ifndef PB_DS_SAMPLE_RANGE_HASHING_HPP #define PB_DS_SAMPLE_RANGE_HASHING_HPP namespace __gnu_pbds { /// A sample range-hashing functor. class sample_range_hashing { public: /// Size type. typedef std::size_t size_type; /// Default constructor. sample_range_hashing(); /// Copy constructor. sample_range_hashing(const sample_range_hashing& other); /// Swaps content. inline void swap(sample_range_hashing& other); protected: /// Notifies the policy object that the container's size has /// changed to argument's size. void notify_resized(size_type); /// Transforms the __hash value hash into a ranged-hash value. inline size_type operator()(size_type ) const; }; } #endif // #ifndef PB_DS_SAMPLE_RANGE_HASHING_HPP 8/ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp000064400000004527152526447520017001 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file mod_based_range_hashing.hpp * Contains a range hashing policy base. */ #ifndef PB_DS_MOD_BASED_RANGE_HASHING_HPP #define PB_DS_MOD_BASED_RANGE_HASHING_HPP namespace __gnu_pbds { namespace detail { /// Mod based range hashing. template class mod_based_range_hashing { protected: typedef Size_Type size_type; void swap(mod_based_range_hashing& other) { std::swap(m_size, other.m_size); } void notify_resized(size_type s) { m_size = s; } inline size_type range_hash(size_type s) const { return s % m_size; } private: size_type m_size; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_MOD_BASED_RANGE_HASHING_HPP 8/ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp000064400000006332152526447520017151 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file mask_based_range_hashing.hpp * Contains a range hashing policy base. */ #ifndef PB_DS_MASK_BASED_RANGE_HASHING_HPP #define PB_DS_MASK_BASED_RANGE_HASHING_HPP namespace __gnu_pbds { namespace detail { /// Range hashing policy. template class mask_based_range_hashing { protected: typedef Size_Type size_type; void swap(mask_based_range_hashing& other) { std::swap(m_mask, other.m_mask); } void notify_resized(size_type size); inline size_type range_hash(size_type hash) const { return size_type(hash & m_mask); } private: size_type m_mask; const static size_type s_num_bits_in_size_type; const static size_type s_highest_bit_1; }; template const typename mask_based_range_hashing::size_type mask_based_range_hashing::s_num_bits_in_size_type = sizeof(typename mask_based_range_hashing::size_type) << 3; template const typename mask_based_range_hashing::size_type mask_based_range_hashing::s_highest_bit_1 = static_cast::size_type>(1) << (s_num_bits_in_size_type - 1); template void mask_based_range_hashing:: notify_resized(size_type size) { size_type i = 0; while (size ^ s_highest_bit_1) { size <<= 1; ++i; } m_mask = 1; i += 2; while (i++ < s_num_bits_in_size_type) m_mask = (m_mask << 1) ^ 1; } } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/hash_fn/sample_probe_fn.hpp000064400000004363152526447520015340 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_probe_fn.hpp * Contains a sample probe policy. */ #ifndef PB_DS_SAMPLE_PROBE_FN_HPP #define PB_DS_SAMPLE_PROBE_FN_HPP namespace __gnu_pbds { /// A sample probe policy. class sample_probe_fn { public: typedef std::size_t size_type; /// Default constructor. sample_probe_fn(); /// Copy constructor. sample_probe_fn(const sample_probe_fn&); /// Swaps content. inline void swap(sample_probe_fn&); protected: /// Returns the i-th offset from the hash value of some key r_key. inline size_type operator()(key_const_reference r_key, size_type i) const; }; } #endif // #ifndef PB_DS_SAMPLE_PROBE_FN_HPP 8/ext/pb_ds/detail/hash_fn/sample_ranged_probe_fn.hpp000064400000005046152526447520016657 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_ranged_probe_fn.hpp * Contains a ranged probe policy. */ #ifndef PB_DS_SAMPLE_RANGED_PROBE_FN_HPP #define PB_DS_SAMPLE_RANGED_PROBE_FN_HPP namespace __gnu_pbds { /// A sample ranged-probe functor. class sample_ranged_probe_fn { public: typedef std::size_t size_type; // Default constructor. sample_ranged_probe_fn(); // Copy constructor. sample_ranged_probe_fn(const sample_ranged_probe_fn&); // Swaps content. inline void swap(sample_ranged_probe_fn&); protected: // Notifies the policy object that the container's __size has // changed to size. void notify_resized(size_type); // Transforms the const key reference r_key into the i-th position // within the table. This method is called for each collision within // the probe sequence. inline size_type operator()(key_const_reference, std::size_t, size_type) const; }; } #endif // #ifndef PB_DS_SAMPLE_RANGED_PROBE_FN_HPP 8/ext/pb_ds/detail/branch_policy/branch_policy.hpp000064400000007677152526447520016242 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file branch_policy/branch_policy.hpp * Contains a base class for branch policies. */ #ifndef PB_DS_BRANCH_POLICY_BASE_HPP #define PB_DS_BRANCH_POLICY_BASE_HPP #include namespace __gnu_pbds { namespace detail { /// Primary template, base class for branch structure policies. template struct branch_policy { protected: typedef typename Node_Itr::value_type it_type; typedef typename std::iterator_traits::value_type value_type; typedef typename value_type::first_type key_type; typedef typename remove_const::type rcvalue_type; typedef typename remove_const::type rckey_type; typedef typename _Alloc::template rebind::other rebind_v; typedef typename _Alloc::template rebind::other rebind_k; typedef typename rebind_v::reference reference; typedef typename rebind_v::const_reference const_reference; typedef typename rebind_v::const_pointer const_pointer; typedef typename rebind_k::const_reference key_const_reference; static inline key_const_reference extract_key(const_reference r_val) { return r_val.first; } virtual it_type end() = 0; it_type end_iterator() const { return const_cast(this)->end(); } virtual ~branch_policy() { } }; /// Specialization for const iterators. template struct branch_policy { protected: typedef typename Node_CItr::value_type it_type; typedef typename std::iterator_traits::value_type value_type; typedef typename remove_const::type rcvalue_type; typedef typename _Alloc::template rebind::other rebind_v; typedef typename rebind_v::reference reference; typedef typename rebind_v::const_reference const_reference; typedef typename rebind_v::const_pointer const_pointer; typedef value_type key_type; typedef typename rebind_v::const_reference key_const_reference; static inline key_const_reference extract_key(const_reference r_val) { return r_val; } virtual it_type end() const = 0; it_type end_iterator() const { return end(); } virtual ~branch_policy() { } }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BRANCH_POLICY_BASE_HPP 8/ext/pb_ds/detail/branch_policy/null_node_metadata.hpp000064400000004513152526447520017227 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file branch_policy/null_node_metadata.hpp * Contains an implementation class for tree-like classes. */ #ifndef PB_DS_0_NODE_METADATA_HPP #define PB_DS_0_NODE_METADATA_HPP #include namespace __gnu_pbds { namespace detail { /// Constant node iterator. template struct dumnode_const_iterator { private: typedef types_traits __traits_type; typedef typename __traits_type::pointer const_iterator; public: typedef const_iterator value_type; typedef const_iterator const_reference; typedef const_reference reference; }; } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/branch_policy/traits.hpp000064400000006266152526447520014725 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file branch_policy/traits.hpp * Contains an implementation class for tree-like classes. */ #ifndef PB_DS_NODE_AND_IT_TRAITS_HPP #define PB_DS_NODE_AND_IT_TRAITS_HPP #include #include #include #include #define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) namespace __gnu_pbds { namespace detail { /// Tree traits class, primary template. template class Node_Update, typename Tag, typename _Alloc> struct tree_traits; /// Trie traits class, primary template. template class Node_Update, typename Tag, typename _Alloc> struct trie_traits; } // namespace detail } // namespace __gnu_pbds #include #include #include #include #undef PB_DS_DEBUG_VERIFY #endif // #ifndef PB_DS_NODE_AND_IT_TRAITS_HPP 8/ext/pb_ds/detail/type_utils.hpp000064400000010337152526447520012776 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/type_utils.hpp * Contains utilities for handnling types. All of these classes are based on * Modern C++ by Andrei Alxandrescu. */ #ifndef PB_DS_TYPE_UTILS_HPP #define PB_DS_TYPE_UTILS_HPP #include #include #include #include #include namespace __gnu_pbds { namespace detail { using std::tr1::is_same; using std::tr1::is_const; using std::tr1::is_pointer; using std::tr1::is_reference; using std::tr1::is_fundamental; using std::tr1::is_member_object_pointer; using std::tr1::is_member_pointer; using std::tr1::is_base_of; using std::tr1::remove_const; using std::tr1::remove_reference; // Need integral_const <-> integral_const, so // because of this use the following typedefs instead of importing // std::tr1's. using std::tr1::integral_constant; typedef std::tr1::integral_constant true_type; typedef std::tr1::integral_constant false_type; using __gnu_cxx::__conditional_type; using __gnu_cxx::__numeric_traits; template struct is_const_pointer { enum { value = is_const::value && is_pointer::value }; }; template struct is_const_reference { enum { value = is_const::value && is_reference::value }; }; template struct is_simple { enum { value = is_fundamental::type>::value || is_pointer::type>::value || is_member_pointer::value }; }; template class is_pair { private: template struct is_pair_imp { enum { value = 0 }; }; template struct is_pair_imp > { enum { value = 1 }; }; public: enum { value = is_pair_imp::value }; }; // Use C++11's static_assert if possible. #if __cplusplus >= 201103L #define PB_DS_STATIC_ASSERT(UNIQUE, E) static_assert(E, #UNIQUE) #else template struct __static_assert; template<> struct __static_assert { }; template struct __static_assert_dumclass { enum { v = 1 }; }; #define PB_DS_STATIC_ASSERT(UNIQUE, E) \ typedef __gnu_pbds::detail::__static_assert_dumclass)> UNIQUE##__static_assert_type #endif template struct type_to_type { typedef Type type; }; } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/list_update_policy/lu_counter_metadata.hpp000064400000005442152526447520020511 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file lu_counter_metadata.hpp * Contains implementation of a lu counter policy's metadata. */ namespace __gnu_pbds { namespace detail { template class lu_counter_policy_base; /// A list-update metadata type that moves elements to the front of /// the list based on the counter algorithm. template class lu_counter_metadata { public: typedef Size_Type size_type; private: lu_counter_metadata(size_type init_count) : m_count(init_count) { } friend class lu_counter_policy_base; mutable size_type m_count; }; /// Base class for list-update counter policy. template class lu_counter_policy_base { protected: typedef Size_Type size_type; lu_counter_metadata operator()(size_type max_size) const { return lu_counter_metadata(std::rand() % max_size); } template bool operator()(Metadata_Reference r_data, size_type m_max_count) const { if (++r_data.m_count != m_max_count) return false; r_data.m_count = 0; return true; } }; } // namespace detail } // namespace __gnu_pbds 8/ext/pb_ds/detail/list_update_policy/sample_update_policy.hpp000064400000005160152526447520020671 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_update_policy.hpp * Contains a sample policy for list update containers. */ #ifndef PB_DS_SAMPLE_UPDATE_POLICY_HPP #define PB_DS_SAMPLE_UPDATE_POLICY_HPP namespace __gnu_pbds { /// A sample list-update policy. struct sample_update_policy { /// Default constructor. sample_update_policy(); /// Copy constructor. sample_update_policy(const sample_update_policy&); /// Swaps content. inline void swap(sample_update_policy& other); protected: /// Metadata on which this functor operates. typedef some_metadata_type metadata_type; /// Creates a metadata object. metadata_type operator()() const; /// Decides whether a metadata object should be moved to the front /// of the list. A list-update based containers object will call /// this method to decide whether to move a node to the front of /// the list. The method shoule return true if the node should be /// moved to the front of the list. bool operator()(metadata_reference) const; }; } #endif 8/ext/pb_ds/detail/cond_dealtor.hpp000064400000005244152526447520013233 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/cond_dealtor.hpp * Contains a conditional deallocator. */ #ifndef PB_DS_COND_DEALTOR_HPP #define PB_DS_COND_DEALTOR_HPP namespace __gnu_pbds { namespace detail { /// Conditional deallocate constructor argument. template class cond_dealtor { typedef typename _Alloc::template rebind __rebind_e; public: typedef typename __rebind_e::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; cond_dealtor(entry_pointer p_e) : m_p_e(p_e), m_no_action_destructor(false) { } ~cond_dealtor() { if (m_no_action_destructor) return; s_alloc.deallocate(m_p_e, 1); } void set_no_action() { m_no_action_destructor = true; } private: entry_pointer m_p_e; bool m_no_action_destructor; static entry_allocator s_alloc; }; template typename cond_dealtor::entry_allocator cond_dealtor::s_alloc; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_COND_DEALTOR_HPP 8/ext/pb_ds/detail/ov_tree_map_/node_iterators.hpp000064400000021153152526447520016253 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/node_iterators.hpp * Contains an implementation class for ov_tree_. */ #ifndef PB_DS_OV_TREE_NODE_ITERATORS_HPP #define PB_DS_OV_TREE_NODE_ITERATORS_HPP #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC \ ov_tree_node_const_it_ /// Const node reference. template class ov_tree_node_const_it_ { protected: typedef typename _Alloc::template rebind< Value_Type>::other::pointer pointer; typedef typename _Alloc::template rebind< Value_Type>::other::const_pointer const_pointer; typedef typename _Alloc::template rebind< Metadata_Type>::other::const_pointer const_metadata_pointer; typedef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC this_type; protected: template inline static Ptr mid_pointer(Ptr p_begin, Ptr p_end) { _GLIBCXX_DEBUG_ASSERT(p_end >= p_begin); return (p_begin + (p_end - p_begin) / 2); } public: typedef trivial_iterator_tag iterator_category; typedef trivial_iterator_difference_type difference_type; typedef typename _Alloc::template rebind< Value_Type>::other::const_pointer value_type; typedef typename _Alloc::template rebind< typename remove_const< Value_Type>::type>::other::const_pointer reference; typedef typename _Alloc::template rebind< typename remove_const< Value_Type>::type>::other::const_pointer const_reference; typedef Metadata_Type metadata_type; typedef typename _Alloc::template rebind< metadata_type>::other::const_reference metadata_const_reference; public: inline ov_tree_node_const_it_(const_pointer p_nd = 0, const_pointer p_begin_nd = 0, const_pointer p_end_nd = 0, const_metadata_pointer p_metadata = 0) : m_p_value(const_cast(p_nd)), m_p_begin_value(const_cast(p_begin_nd)), m_p_end_value(const_cast(p_end_nd)), m_p_metadata(p_metadata) { } inline const_reference operator*() const { return m_p_value; } inline metadata_const_reference get_metadata() const { enum { has_metadata = !is_same::value }; PB_DS_STATIC_ASSERT(should_have_metadata, has_metadata); _GLIBCXX_DEBUG_ASSERT(m_p_metadata != 0); return *m_p_metadata; } /// Returns the node iterator associated with the left node. inline this_type get_l_child() const { if (m_p_begin_value == m_p_value) return (this_type(m_p_begin_value, m_p_begin_value, m_p_begin_value)); const_metadata_pointer p_begin_metadata = m_p_metadata - (m_p_value - m_p_begin_value); return (this_type(mid_pointer(m_p_begin_value, m_p_value), m_p_begin_value, m_p_value, mid_pointer(p_begin_metadata, m_p_metadata))); } /// Returns the node iterator associated with the right node. inline this_type get_r_child() const { if (m_p_value == m_p_end_value) return (this_type(m_p_end_value, m_p_end_value, m_p_end_value)); const_metadata_pointer p_end_metadata = m_p_metadata + (m_p_end_value - m_p_value); return (this_type(mid_pointer(m_p_value + 1, m_p_end_value), m_p_value + 1, m_p_end_value,(m_p_metadata == 0) ? 0 : mid_pointer(m_p_metadata + 1, p_end_metadata))); } inline bool operator==(const this_type& other) const { const bool is_end = m_p_begin_value == m_p_end_value; const bool is_other_end = other.m_p_begin_value == other.m_p_end_value; if (is_end) return (is_other_end); if (is_other_end) return (is_end); return m_p_value == other.m_p_value; } inline bool operator!=(const this_type& other) const { return !operator==(other); } public: pointer m_p_value; pointer m_p_begin_value; pointer m_p_end_value; const_metadata_pointer m_p_metadata; }; #define PB_DS_OV_TREE_NODE_ITERATOR_C_DEC \ ov_tree_node_it_ /// Node reference. template class ov_tree_node_it_ : public PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC { private: typedef PB_DS_OV_TREE_NODE_ITERATOR_C_DEC this_type; typedef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC base_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::const_metadata_pointer const_metadata_pointer; public: typedef trivial_iterator_tag iterator_category; typedef trivial_iterator_difference_type difference_type; typedef typename _Alloc::template rebind< Value_Type>::other::pointer value_type; typedef typename _Alloc::template rebind< typename remove_const< Value_Type>::type>::other::pointer reference; typedef typename _Alloc::template rebind< typename remove_const< Value_Type>::type>::other::pointer const_reference; inline ov_tree_node_it_(const_pointer p_nd = 0, const_pointer p_begin_nd = 0, const_pointer p_end_nd = 0, const_metadata_pointer p_metadata = 0) : base_type(p_nd, p_begin_nd, p_end_nd, p_metadata) { } /// Access. inline reference operator*() const { return reference(base_type::m_p_value); } /// Returns the node reference associated with the left node. inline ov_tree_node_it_ get_l_child() const { if (base_type::m_p_begin_value == base_type::m_p_value) return (this_type(base_type::m_p_begin_value, base_type::m_p_begin_value, base_type::m_p_begin_value)); const_metadata_pointer p_begin_metadata = base_type::m_p_metadata - (base_type::m_p_value - base_type::m_p_begin_value); return (this_type(base_type::mid_pointer(base_type::m_p_begin_value, base_type::m_p_value), base_type::m_p_begin_value, base_type::m_p_value, base_type::mid_pointer(p_begin_metadata, base_type::m_p_metadata))); } /// Returns the node reference associated with the right node. inline ov_tree_node_it_ get_r_child() const { if (base_type::m_p_value == base_type::m_p_end_value) return this_type(base_type::m_p_end_value, base_type::m_p_end_value, base_type::m_p_end_value); const_metadata_pointer p_end_metadata = base_type::m_p_metadata + (base_type::m_p_end_value - base_type::m_p_value); return (this_type(base_type::mid_pointer(base_type::m_p_value + 1, base_type::m_p_end_value), base_type::m_p_value + 1, base_type::m_p_end_value,(base_type::m_p_metadata == 0)? 0 : base_type::mid_pointer(base_type::m_p_metadata + 1, p_end_metadata))); } }; #undef PB_DS_OV_TREE_NODE_ITERATOR_C_DEC #undef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp000064400000036006152526447520015674 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/ov_tree_map_.hpp * Contains an implementation class for ov_tree. */ #include #include #include #include #include #include #include #include #ifdef _GLIBCXX_DEBUG #include #endif #include #include #include #include #include #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_OV_TREE_NAME ov_tree_map #define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_node_const_iterator_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_OV_TREE_NAME ov_tree_set #define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_node_const_iterator_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_OV_TREE_NAME #define PB_DS_OV_TREE_TRAITS_BASE \ types_traits #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base, \ typename _Alloc::template rebind::other::const_reference> #endif #ifdef PB_DS_TREE_TRACE #define PB_DS_TREE_TRACE_BASE_C_DEC \ tree_trace_base #endif #ifndef PB_DS_CHECK_KEY_EXISTS # error Missing definition #endif /** * @brief Ordered-vector tree associative-container. * @ingroup branch-detail */ template class PB_DS_OV_TREE_NAME : #ifdef _GLIBCXX_DEBUG protected PB_DS_DEBUG_MAP_BASE_C_DEC, #endif #ifdef PB_DS_TREE_TRACE public PB_DS_TREE_TRACE_BASE_C_DEC, #endif public Cmp_Fn, public Node_And_It_Traits::node_update, public PB_DS_OV_TREE_TRAITS_BASE { private: typedef PB_DS_OV_TREE_TRAITS_BASE traits_base; typedef Node_And_It_Traits traits_type; typedef typename remove_const::type non_const_value_type; typedef typename _Alloc::template rebind::other value_allocator; typedef typename value_allocator::pointer value_vector; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif #ifdef PB_DS_TREE_TRACE typedef PB_DS_TREE_TRACE_BASE_C_DEC trace_base; #endif typedef typename traits_base::pointer mapped_pointer_; typedef typename traits_base::const_pointer mapped_const_pointer_; typedef typename traits_type::metadata_type metadata_type; typedef typename _Alloc::template rebind::other metadata_allocator; typedef typename metadata_allocator::pointer metadata_pointer; typedef typename metadata_allocator::const_reference metadata_const_reference; typedef typename metadata_allocator::reference metadata_reference; typedef typename traits_type::null_node_update_pointer null_node_update_pointer; public: typedef ov_tree_tag container_category; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Cmp_Fn cmp_fn; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; typedef const_pointer point_const_iterator; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef pointer point_iterator; #else typedef point_const_iterator point_iterator; #endif typedef point_iterator iterator; typedef point_const_iterator const_iterator; /// Conditional destructor. template class cond_dtor { public: cond_dtor(value_vector a_vec, iterator& r_last_it, Size_Type total_size) : m_a_vec(a_vec), m_r_last_it(r_last_it), m_max_size(total_size), m_no_action(false) { } ~cond_dtor() { if (m_no_action) return; iterator it = m_a_vec; while (it != m_r_last_it) { it->~value_type(); ++it; } if (m_max_size > 0) value_allocator().deallocate(m_a_vec, m_max_size); } inline void set_no_action() { m_no_action = true; } protected: value_vector m_a_vec; iterator& m_r_last_it; const Size_Type m_max_size; bool m_no_action; }; typedef typename traits_type::node_update node_update; typedef typename traits_type::node_iterator node_iterator; typedef typename traits_type::node_const_iterator node_const_iterator; PB_DS_OV_TREE_NAME(); PB_DS_OV_TREE_NAME(const Cmp_Fn&); PB_DS_OV_TREE_NAME(const Cmp_Fn&, const node_update&); PB_DS_OV_TREE_NAME(const PB_DS_CLASS_C_DEC&); ~PB_DS_OV_TREE_NAME(); void swap(PB_DS_CLASS_C_DEC&); template void copy_from_range(It, It); inline size_type max_size() const; inline bool empty() const; inline size_type size() const; Cmp_Fn& get_cmp_fn(); const Cmp_Fn& get_cmp_fn() const; inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_ASSERT_VALID((*this)) point_iterator it = lower_bound(r_key); if (it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it))) { PB_DS_CHECK_KEY_EXISTS(r_key) PB_DS_ASSERT_VALID((*this)) return it->second; } return insert_new_val(it, std::make_pair(r_key, mapped_type()))->second; #else insert(r_key); return traits_base::s_null_type; #endif } inline std::pair insert(const_reference r_value) { PB_DS_ASSERT_VALID((*this)) key_const_reference r_key = PB_DS_V2F(r_value); point_iterator it = lower_bound(r_key); if (it != end()&& !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it))) { PB_DS_ASSERT_VALID((*this)) PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(it, false); } return std::make_pair(insert_new_val(it, r_value), true); } inline point_iterator lower_bound(key_const_reference r_key) { pointer it = m_a_values; pointer e_it = m_a_values + m_size; while (it != e_it) { pointer mid_it = it + ((e_it - it) >> 1); if (cmp_fn::operator()(PB_DS_V2F(*mid_it), r_key)) it = ++mid_it; else e_it = mid_it; } return it; } inline point_const_iterator lower_bound(key_const_reference r_key) const { return const_cast(*this).lower_bound(r_key); } inline point_iterator upper_bound(key_const_reference r_key) { iterator pot_it = lower_bound(r_key); if (pot_it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it))) { PB_DS_CHECK_KEY_EXISTS(r_key) return ++pot_it; } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return pot_it; } inline point_const_iterator upper_bound(key_const_reference r_key) const { return const_cast(*this).upper_bound(r_key); } inline point_iterator find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) iterator pot_it = lower_bound(r_key); if (pot_it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it))) { PB_DS_CHECK_KEY_EXISTS(r_key) return pot_it; } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } inline point_const_iterator find(key_const_reference r_key) const { return (const_cast(*this).find(r_key)); } bool erase(key_const_reference); template inline size_type erase_if(Pred); inline iterator erase(iterator it) { return erase_imp(it); } void clear(); void join(PB_DS_CLASS_C_DEC&); void split(key_const_reference, PB_DS_CLASS_C_DEC&); inline iterator begin() { return m_a_values; } inline const_iterator begin() const { return m_a_values; } inline iterator end() { return m_end_it; } inline const_iterator end() const { return m_end_it; } /// Returns a const node_iterator corresponding to the node at the /// root of the tree. inline node_const_iterator node_begin() const; /// Returns a node_iterator corresponding to the node at the /// root of the tree. inline node_iterator node_begin(); /// Returns a const node_iterator corresponding to a node just /// after a leaf of the tree. inline node_const_iterator node_end() const; /// Returns a node_iterator corresponding to a node just /// after a leaf of the tree. inline node_iterator node_end(); private: inline void update(node_iterator, null_node_update_pointer); template void update(node_iterator, Node_Update*); void reallocate_metadata(null_node_update_pointer, size_type); template void reallocate_metadata(Node_Update_*, size_type); template void copy_from_ordered_range(It, It); void value_swap(PB_DS_CLASS_C_DEC&); template void copy_from_ordered_range(It, It, It, It); template inline static Ptr mid_pointer(Ptr p_begin, Ptr p_end) { _GLIBCXX_DEBUG_ASSERT(p_end >= p_begin); return (p_begin + (p_end - p_begin) / 2); } inline iterator insert_new_val(iterator it, const_reference r_value) { #ifdef PB_DS_REGRESSION typename _Alloc::group_adjustor adjust(m_size); #endif PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_value)) value_vector a_values = s_value_alloc.allocate(m_size + 1); iterator source_it = begin(); iterator source_end_it = end(); iterator target_it = a_values; iterator ret_it; cond_dtor cd(a_values, target_it, m_size + 1); while (source_it != it) { new (const_cast(static_cast(target_it))) value_type(*source_it++); ++target_it; } new (const_cast(static_cast(ret_it = target_it))) value_type(r_value); ++target_it; while (source_it != source_end_it) { new (const_cast(static_cast(target_it))) value_type(*source_it++); ++target_it; } reallocate_metadata((node_update*)this, m_size + 1); cd.set_no_action(); if (m_size != 0) { cond_dtor cd1(m_a_values, m_end_it, m_size); } ++m_size; m_a_values = a_values; m_end_it = m_a_values + m_size; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_value))); update(node_begin(), (node_update* )this); PB_DS_ASSERT_VALID((*this)) return ret_it; } #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void assert_iterators(const char*, int) const; #endif template It erase_imp(It); inline node_const_iterator PB_DS_node_begin_imp() const; inline node_const_iterator PB_DS_node_end_imp() const; inline node_iterator PB_DS_node_begin_imp(); inline node_iterator PB_DS_node_end_imp(); private: static value_allocator s_value_alloc; static metadata_allocator s_metadata_alloc; value_vector m_a_values; metadata_pointer m_a_metadata; iterator m_end_it; size_type m_size; }; #include #include #include #include #include #include #include #include #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_OV_TREE_NAME #undef PB_DS_OV_TREE_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #ifdef PB_DS_TREE_TRACE #undef PB_DS_TREE_TRACE_BASE_C_DEC #endif #undef PB_DS_CONST_NODE_ITERATOR_NAME } // namespace detail } // namespace __gnu_pbds 8/ext/pb_ds/detail/ov_tree_map_/policy_access_fn_imps.hpp000064400000003537152526447520017573 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/policy_access_fn_imps.hpp * Contains an implementation class for ov_tree. */ PB_DS_CLASS_T_DEC Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() { return *this; } PB_DS_CLASS_T_DEC const Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() const { return *this; } 8/ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp000064400000015325152526447520021777 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/constructors_destructor_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::value_allocator PB_DS_CLASS_C_DEC::s_value_alloc; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::metadata_allocator PB_DS_CLASS_C_DEC::s_metadata_alloc; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_OV_TREE_NAME() : m_a_values(0), m_a_metadata(0), m_end_it(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_OV_TREE_NAME(const Cmp_Fn& r_cmp_fn) : cmp_fn(r_cmp_fn), m_a_values(0), m_a_metadata(0), m_end_it(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_OV_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_nodeu) : cmp_fn(r_cmp_fn), node_update(r_nodeu), m_a_values(0), m_a_metadata(0), m_end_it(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_OV_TREE_NAME(const PB_DS_CLASS_C_DEC& other) : #ifdef PB_DS_TREE_TRACE trace_base(other), #endif cmp_fn(other), node_update(other), m_a_values(0), m_a_metadata(0), m_end_it(0), m_size(0) { copy_from_ordered_range(other.begin(), other.end()); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { #ifdef PB_DS_DATA_TRUE_INDICATOR typedef std::map::other> map_type; #else typedef std::set::other> map_type; #endif map_type m(first_it, last_it); copy_from_ordered_range(m.begin(), m.end()); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_ordered_range(It first_it, It last_it) { const size_type len = std::distance(first_it, last_it); if (len == 0) return; value_vector a_values = s_value_alloc.allocate(len); iterator target_it = a_values; It source_it = first_it; It source_end_it = last_it; cond_dtor cd(a_values, target_it, len); while (source_it != source_end_it) { void* __v = const_cast(static_cast(target_it)); new (__v) value_type(*source_it++); ++target_it; } reallocate_metadata((node_update*)this, len); cd.set_no_action(); m_a_values = a_values; m_size = len; m_end_it = m_a_values + m_size; update(PB_DS_node_begin_imp(), (node_update*)this); #ifdef _GLIBCXX_DEBUG for (const_iterator dbg_it = m_a_values; dbg_it != m_end_it; ++dbg_it) debug_base::insert_new(PB_DS_V2F(*dbg_it)); #endif } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_ordered_range(It first_it, It last_it, It other_first_it, It other_last_it) { clear(); const size_type len = std::distance(first_it, last_it) + std::distance(other_first_it, other_last_it); value_vector a_values = s_value_alloc.allocate(len); iterator target_it = a_values; It source_it = first_it; It source_end_it = last_it; cond_dtor cd(a_values, target_it, len); while (source_it != source_end_it) { new (const_cast(static_cast(target_it))) value_type(*source_it++); ++target_it; } source_it = other_first_it; source_end_it = other_last_it; while (source_it != source_end_it) { new (const_cast(static_cast(target_it))) value_type(*source_it++); ++target_it; } reallocate_metadata((node_update* )this, len); cd.set_no_action(); m_a_values = a_values; m_size = len; m_end_it = m_a_values + m_size; update(PB_DS_node_begin_imp(), (node_update* )this); #ifdef _GLIBCXX_DEBUG for (const_iterator dbg_it = m_a_values; dbg_it != m_end_it; ++dbg_it) debug_base::insert_new(PB_DS_V2F(*dbg_it)); #endif } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) value_swap(other); std::swap(static_cast(*this), static_cast(other)); std::swap(static_cast(*this), static_cast(other)); PB_DS_ASSERT_VALID(other) PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);) std::swap(m_a_values, other.m_a_values); std::swap(m_a_metadata, other.m_a_metadata); std::swap(m_size, other.m_size); std::swap(m_end_it, other.m_end_it); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_OV_TREE_NAME() { PB_DS_ASSERT_VALID((*this)) cond_dtor cd(m_a_values, m_end_it, m_size); reallocate_metadata((node_update*)this, 0); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update(node_iterator, null_node_update_pointer) { } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: update(node_iterator nd_it, Node_Update* p_update) { node_const_iterator end_it = PB_DS_node_end_imp(); if (nd_it != end_it) { update(nd_it.get_l_child(), p_update); update(nd_it.get_r_child(), p_update); node_update::operator()(nd_it, end_it); } } 8/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp000064400000004044152526447520015700 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/info_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { PB_DS_ASSERT_VALID((*this)) return m_size; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_value_alloc.max_size(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return size() == 0; } 8/ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp000064400000006441152526447520016764 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/iterators_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_begin() const { return PB_DS_node_begin_imp(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_end() const { return PB_DS_node_end_imp(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_begin() { return PB_DS_node_begin_imp(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_end() { return PB_DS_node_end_imp(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: PB_DS_node_begin_imp() const { return node_const_iterator(const_cast(mid_pointer(begin(), end())), const_cast(begin()), const_cast(end()),(m_a_metadata == 0)? 0 : mid_pointer(m_a_metadata, m_a_metadata + m_size)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: PB_DS_node_end_imp() const { return node_const_iterator(end(), end(), end(), (m_a_metadata == 0) ? 0 : m_a_metadata + m_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: PB_DS_node_begin_imp() { return node_iterator(mid_pointer(begin(), end()), begin(), end(), (m_a_metadata == 0) ? 0 : mid_pointer(m_a_metadata, m_a_metadata + m_size)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: PB_DS_node_end_imp() { return node_iterator(end(), end(), end(),(m_a_metadata == 0) ? 0 : m_a_metadata + m_size); } 8/ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp000064400000005402152526447520016032 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/debug_fn_imps.hpp * Contains an implementation class for ov_tree_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { if (m_a_values == 0 || m_end_it == 0 || m_size == 0) PB_DS_DEBUG_VERIFY(m_a_values == 0 && m_end_it == 0 && m_size == 0); assert_iterators(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_iterators(const char* __file, int __line) const { debug_base::check_size(m_size, __file, __line); size_type iterated_num = 0; const_iterator prev_it = end(); PB_DS_DEBUG_VERIFY(m_end_it == m_a_values + m_size); for (const_iterator it = begin(); it != end(); ++it) { ++iterated_num; debug_base::check_key_exists(PB_DS_V2F(*it), __file, __line); PB_DS_DEBUG_VERIFY(lower_bound(PB_DS_V2F(*it)) == it); const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*it)); --upper_bound_it; PB_DS_DEBUG_VERIFY(upper_bound_it == it); if (prev_it != end()) PB_DS_DEBUG_VERIFY(Cmp_Fn::operator()(PB_DS_V2F(*prev_it), PB_DS_V2F(*it))); prev_it = it; } PB_DS_DEBUG_VERIFY(iterated_num == m_size); } #endif 8/ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp000064400000004341152526447520016251 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/insert_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: reallocate_metadata(null_node_update_pointer, size_type) { } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: reallocate_metadata(Node_Update_* , size_type new_size) { metadata_pointer a_new_metadata_vec =(new_size == 0) ? 0 : s_metadata_alloc.allocate(new_size); if (m_a_metadata != 0) { for (size_type i = 0; i < m_size; ++i) m_a_metadata[i].~metadata_type(); s_metadata_alloc.deallocate(m_a_metadata, m_size); } std::swap(m_a_metadata, a_new_metadata_vec); } 8/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp000064400000011565152526447520016052 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/erase_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { PB_DS_ASSERT_VALID((*this)) if (m_size == 0) { return; } else { reallocate_metadata((node_update* )this, 0); cond_dtor cd(m_a_values, m_end_it, m_size); } _GLIBCXX_DEBUG_ONLY(debug_base::clear();) m_a_values = 0; m_size = 0; m_end_it = m_a_values; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) #ifdef PB_DS_REGRESSION typename _Alloc::group_adjustor adjust(m_size); #endif size_type new_size = 0; size_type num_val_ersd = 0; for (iterator source_it = begin(); source_it != m_end_it; ++source_it) if (!pred(*source_it)) ++new_size; else ++num_val_ersd; if (new_size == 0) { clear(); return num_val_ersd; } value_vector a_new_values = s_value_alloc.allocate(new_size); iterator target_it = a_new_values; cond_dtor cd(a_new_values, target_it, new_size); _GLIBCXX_DEBUG_ONLY(debug_base::clear()); for (iterator source_it = begin(); source_it != m_end_it; ++source_it) { if (!pred(*source_it)) { new (const_cast(static_cast(target_it))) value_type(*source_it); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(*source_it))); ++target_it; } } reallocate_metadata((node_update*)this, new_size); cd.set_no_action(); { cond_dtor cd1(m_a_values, m_end_it, m_size); } m_a_values = a_new_values; m_size = new_size; m_end_it = target_it; update(node_begin(), (node_update*)this); PB_DS_ASSERT_VALID((*this)) return num_val_ersd; } PB_DS_CLASS_T_DEC template It PB_DS_CLASS_C_DEC:: erase_imp(It it) { PB_DS_ASSERT_VALID((*this)) if (it == end()) return end(); PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(*it)) #ifdef PB_DS_REGRESSION typename _Alloc::group_adjustor adjust(m_size); #endif _GLIBCXX_DEBUG_ASSERT(m_size > 0); value_vector a_values = s_value_alloc.allocate(m_size - 1); iterator source_it = begin(); iterator source_end_it = end(); iterator target_it = a_values; iterator ret_it = end(); cond_dtor cd(a_values, target_it, m_size - 1); _GLIBCXX_DEBUG_ONLY(size_type cnt = 0;) while (source_it != source_end_it) { if (source_it != it) { _GLIBCXX_DEBUG_ONLY(++cnt;) _GLIBCXX_DEBUG_ASSERT(cnt != m_size); new (const_cast(static_cast(target_it))) value_type(*source_it); ++target_it; } else ret_it = target_it; ++source_it; } _GLIBCXX_DEBUG_ASSERT(m_size > 0); reallocate_metadata((node_update*)this, m_size - 1); cd.set_no_action(); _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(*it));) { cond_dtor cd1(m_a_values, m_end_it, m_size); } m_a_values = a_values; --m_size; m_end_it = m_a_values + m_size; update(node_begin(), (node_update*)this); PB_DS_ASSERT_VALID((*this)) return It(ret_it); } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { point_iterator it = find(r_key); if (it == end()) return false; erase(it); return true; } 8/ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp000064400000007276152526447520017131 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/split_join_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (m_size == 0) { other.clear(); return; } if (Cmp_Fn::operator()(r_key, PB_DS_V2F(*begin()))) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(*(end() - 1)))) { return; } if (m_size == 1) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } iterator it = upper_bound(r_key); PB_DS_CLASS_C_DEC new_other(other, other); new_other.copy_from_ordered_range(it, end()); PB_DS_CLASS_C_DEC new_this(*this, *this); new_this.copy_from_ordered_range(begin(), it); // No exceptions from this point. other.update(other.node_begin(), (node_update*)(&other)); update(node_begin(), (node_update*)this); other.value_swap(new_other); value_swap(new_this); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (other.m_size == 0) return; if (m_size == 0) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } const bool greater = Cmp_Fn::operator()(PB_DS_V2F(*(end() - 1)), PB_DS_V2F(*other.begin())); const bool lesser = Cmp_Fn::operator()(PB_DS_V2F(*(other.end() - 1)), PB_DS_V2F(*begin())); if (!greater && !lesser) __throw_join_error(); PB_DS_CLASS_C_DEC new_this(*this, *this); if (greater) new_this.copy_from_ordered_range(begin(), end(), other.begin(), other.end()); else new_this.copy_from_ordered_range(other.begin(), other.end(), begin(), end()); // No exceptions from this point. value_swap(new_this); other.clear(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } 8/ext/pb_ds/detail/ov_tree_map_/traits.hpp000064400000010722152526447520014540 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/traits.hpp * Contains an implementation class for ov_tree_. */ #ifndef PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP #define PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP #include namespace __gnu_pbds { namespace detail { /// Tree traits. /// @ingroup traits template class Node_Update, typename _Alloc> struct tree_traits< Key, Mapped, Cmp_Fn, Node_Update, ov_tree_tag, _Alloc> { private: typedef typename types_traits< Key, Mapped, _Alloc, false>::value_type value_type; public: typedef typename tree_node_metadata_dispatch< Key, Mapped, Cmp_Fn, Node_Update, _Alloc>::type metadata_type; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef ov_tree_node_const_it_< value_type, metadata_type, _Alloc> node_const_iterator; typedef ov_tree_node_it_< value_type, metadata_type, _Alloc> node_iterator; typedef Node_Update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc> node_update; typedef __gnu_pbds::null_node_update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc>* null_node_update_pointer; }; /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct tree_traits< Key, null_type, Cmp_Fn, Node_Update, ov_tree_tag, _Alloc> { private: typedef typename types_traits< Key, null_type, _Alloc, false>::value_type value_type; public: typedef typename tree_node_metadata_dispatch< Key, null_type, Cmp_Fn, Node_Update, _Alloc>::type metadata_type; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef ov_tree_node_const_it_< value_type, metadata_type, _Alloc> node_const_iterator; typedef node_const_iterator node_iterator; typedef Node_Update< node_const_iterator, node_const_iterator, Cmp_Fn, _Alloc> node_update; typedef __gnu_pbds::null_node_update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc>* null_node_update_pointer; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP 8/ext/pb_ds/detail/pairing_heap_/pairing_heap_.hpp000064400000012615152526447520016150 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/pairing_heap_.hpp * Contains an implementation class for a pairing heap. */ /* * Pairing heap: * Michael L. Fredman, Robert Sedgewick, Daniel Dominic Sleator, * and Robert Endre Tarjan, The Pairing Heap: * A New Form of Self-Adjusting Heap, Algorithmica, 1(1):111-129, 1986. */ #include #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ pairing_heap #ifdef _GLIBCXX_DEBUG #define PB_DS_P_HEAP_BASE \ left_child_next_sibling_heap #else #define PB_DS_P_HEAP_BASE \ left_child_next_sibling_heap #endif /** * Pairing heap. * * @ingroup heap-detail */ template class pairing_heap : public PB_DS_P_HEAP_BASE { private: typedef PB_DS_P_HEAP_BASE base_type; typedef typename base_type::node_pointer node_pointer; typedef typename _Alloc::template rebind::other __rebind_a; public: typedef Value_Type value_type; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename __rebind_a::pointer pointer; typedef typename __rebind_a::const_pointer const_pointer; typedef typename __rebind_a::reference reference; typedef typename __rebind_a::const_reference const_reference; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator iterator; pairing_heap(); pairing_heap(const Cmp_Fn&); pairing_heap(const pairing_heap&); void swap(pairing_heap&); ~pairing_heap(); inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline const_reference top() const; void pop(); void erase(point_iterator); template size_type erase_if(Pred); template void split(Pred, pairing_heap&); void join(pairing_heap&); protected: template void copy_from_range(It, It); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif private: inline void push_imp(node_pointer); node_pointer join_node_children(node_pointer); node_pointer forward_join(node_pointer, node_pointer); node_pointer back_join(node_pointer, node_pointer); void remove_node(node_pointer); }; #define PB_DS_ASSERT_NODE_CONSISTENT(_Node, _Bool) \ _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(_Node, _Bool, \ __FILE__, __LINE__);) #include #include #include #include #include #include #undef PB_DS_ASSERT_NODE_CONSISTENT #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_P_HEAP_BASE } // namespace detail } // namespace __gnu_pbds 8/ext/pb_ds/detail/pairing_heap_/constructors_destructor_fn_imps.hpp000064400000004712152526447520022123 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) push(*(first_it++)); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: pairing_heap() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: pairing_heap(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: pairing_heap(const PB_DS_CLASS_C_DEC& other) : base_type(other) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) base_type::swap(other); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~pairing_heap() { } 8/ext/pb_ds/detail/pairing_heap_/find_fn_imps.hpp000064400000003621152526447520016013 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/find_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top() const { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); return base_type::m_p_root->m_value; } 8/ext/pb_ds/detail/pairing_heap_/debug_fn_imps.hpp000064400000003714152526447520016164 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/debug_fn_imps.hpp * Contains an implementation class for a pairing heap. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(base_type::m_p_root == 0 || base_type::m_p_root->m_p_next_sibling == 0); base_type::assert_valid(__file, __line); } #endif 8/ext/pb_ds/detail/pairing_heap_/insert_fn_imps.hpp000064400000005603152526447520016401 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/insert_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) node_pointer p_new_nd = base_type::get_new_node_for_insert(r_val); push_imp(p_new_nd); PB_DS_ASSERT_VALID((*this)) return point_iterator(p_new_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: push_imp(node_pointer p_nd) { p_nd->m_p_l_child = 0; if (base_type::m_p_root == 0) { p_nd->m_p_next_sibling = p_nd->m_p_prev_or_parent = 0; base_type::m_p_root = p_nd; } else if (Cmp_Fn::operator()(base_type::m_p_root->m_value, p_nd->m_value)) { p_nd->m_p_next_sibling = p_nd->m_p_prev_or_parent = 0; base_type::make_child_of(base_type::m_p_root, p_nd); PB_DS_ASSERT_NODE_CONSISTENT(p_nd, false) base_type::m_p_root = p_nd; } else { base_type::make_child_of(p_nd, base_type::m_p_root); PB_DS_ASSERT_NODE_CONSISTENT(base_type::m_p_root, false) } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID((*this)) remove_node(it.m_p_nd); it.m_p_nd->m_value = r_new_val; push_imp(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) } 8/ext/pb_ds/detail/pairing_heap_/erase_fn_imps.hpp000064400000016027152526447520016176 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/erase_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: pop() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); node_pointer p_new_root = join_node_children(base_type::m_p_root); PB_DS_ASSERT_NODE_CONSISTENT(p_new_root, false) if (p_new_root != 0) p_new_root->m_p_prev_or_parent = 0; base_type::actual_erase_node(base_type::m_p_root); base_type::m_p_root = p_new_root; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); remove_node(it.m_p_nd); base_type::actual_erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_node(node_pointer p_nd) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); node_pointer p_new_child = join_node_children(p_nd); PB_DS_ASSERT_NODE_CONSISTENT(p_new_child, false) if (p_nd == base_type::m_p_root) { if (p_new_child != 0) p_new_child->m_p_prev_or_parent = 0; base_type::m_p_root = p_new_child; PB_DS_ASSERT_NODE_CONSISTENT(base_type::m_p_root, false) return; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_prev_or_parent != 0); if (p_nd->m_p_prev_or_parent->m_p_l_child == p_nd) { if (p_new_child != 0) { p_new_child->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; p_new_child->m_p_next_sibling = p_nd->m_p_next_sibling; if (p_new_child->m_p_next_sibling != 0) p_new_child->m_p_next_sibling->m_p_prev_or_parent = p_new_child; p_nd->m_p_prev_or_parent->m_p_l_child = p_new_child; PB_DS_ASSERT_NODE_CONSISTENT(p_nd->m_p_prev_or_parent, false) return; } p_nd->m_p_prev_or_parent->m_p_l_child = p_nd->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; PB_DS_ASSERT_NODE_CONSISTENT(p_nd->m_p_prev_or_parent, false) return; } if (p_new_child != 0) { p_new_child->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; p_new_child->m_p_next_sibling = p_nd->m_p_next_sibling; if (p_new_child->m_p_next_sibling != 0) p_new_child->m_p_next_sibling->m_p_prev_or_parent = p_new_child; p_new_child->m_p_prev_or_parent->m_p_next_sibling = p_new_child; PB_DS_ASSERT_NODE_CONSISTENT(p_nd->m_p_prev_or_parent, false) return; } p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; PB_DS_ASSERT_NODE_CONSISTENT(p_nd->m_p_prev_or_parent, false) } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: join_node_children(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); node_pointer p_ret = p_nd->m_p_l_child; if (p_ret == 0) return 0; while (p_ret->m_p_next_sibling != 0) p_ret = forward_join(p_ret, p_ret->m_p_next_sibling); while (p_ret->m_p_prev_or_parent != p_nd) p_ret = back_join(p_ret->m_p_prev_or_parent, p_ret); PB_DS_ASSERT_NODE_CONSISTENT(p_ret, false) return p_ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: forward_join(node_pointer p_nd, node_pointer p_next) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling == p_next); if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) { p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; base_type::make_child_of(p_nd, p_next); return p_next->m_p_next_sibling == 0 ? p_next : p_next->m_p_next_sibling; } if (p_next->m_p_next_sibling != 0) { p_next->m_p_next_sibling->m_p_prev_or_parent = p_nd; p_nd->m_p_next_sibling = p_next->m_p_next_sibling; base_type::make_child_of(p_next, p_nd); return p_nd->m_p_next_sibling; } p_nd->m_p_next_sibling = 0; base_type::make_child_of(p_next, p_nd); PB_DS_ASSERT_NODE_CONSISTENT(p_nd, false) return p_nd; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: back_join(node_pointer p_nd, node_pointer p_next) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_next->m_p_next_sibling == 0); if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) { p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; base_type::make_child_of(p_nd, p_next); PB_DS_ASSERT_NODE_CONSISTENT(p_next, false) return p_next; } p_nd->m_p_next_sibling = 0; base_type::make_child_of(p_next, p_nd); PB_DS_ASSERT_NODE_CONSISTENT(p_nd, false) return p_nd; } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) if (base_type::empty()) { PB_DS_ASSERT_VALID((*this)) return 0; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); size_type ersd = 0; while (p_out != 0) { ++ersd; node_pointer p_next = p_out->m_p_next_sibling; base_type::actual_erase_node(p_out); p_out = p_next; } node_pointer p_cur = base_type::m_p_root; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; p_cur->m_p_l_child = p_cur->m_p_next_sibling = p_cur->m_p_prev_or_parent = 0; push_imp(p_cur); p_cur = p_next; } PB_DS_ASSERT_VALID((*this)) return ersd; } 8/ext/pb_ds/detail/pairing_heap_/split_join_fn_imps.hpp000064400000007172152526447520017252 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/split_join_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) other.clear(); if (base_type::empty()) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); while (p_out != 0) { _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); --base_type::m_size; ++other.m_size; node_pointer p_next = p_out->m_p_next_sibling; p_out->m_p_l_child = p_out->m_p_next_sibling = p_out->m_p_prev_or_parent = 0; other.push_imp(p_out); p_out = p_next; } PB_DS_ASSERT_VALID(other) node_pointer p_cur = base_type::m_p_root; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; p_cur->m_p_l_child = p_cur->m_p_next_sibling = p_cur->m_p_prev_or_parent = 0; push_imp(p_cur); p_cur = p_next; } PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (other.m_p_root == 0) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } if (base_type::m_p_root == 0) base_type::m_p_root = other.m_p_root; else if (Cmp_Fn::operator()(base_type::m_p_root->m_value, other.m_p_root->m_value)) { base_type::make_child_of(base_type::m_p_root, other.m_p_root); PB_DS_ASSERT_NODE_CONSISTENT(other.m_p_root, false) base_type::m_p_root = other.m_p_root; } else { base_type::make_child_of(other.m_p_root, base_type::m_p_root); PB_DS_ASSERT_NODE_CONSISTENT(base_type::m_p_root, false) } base_type::m_size += other.m_size; other.m_p_root = 0; other.m_size = 0; PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } 8/ext/pb_ds/detail/container_base_dispatch.hpp000064400000031500152526447520015423 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file container_base_dispatch.hpp * Contains associative container dispatching. */ #ifndef PB_DS_ASSOC_CNTNR_BASE_DS_DISPATCHER_HPP #define PB_DS_ASSOC_CNTNR_BASE_DS_DISPATCHER_HPP #include #define PB_DS_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);) #define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) #define PB_DS_CHECK_KEY_EXISTS(_Key) \ _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(_Key, __FILE__, __LINE__);) #define PB_DS_CHECK_KEY_DOES_NOT_EXIST(_Key) \ _GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(_Key, \ __FILE__, __LINE__);) #define PB_DS_DATA_TRUE_INDICATOR #define PB_DS_V2F(X) (X).first #define PB_DS_V2S(X) (X).second #define PB_DS_EP2VP(X)& ((X)->m_value) #include #include #include #include #include #include #include #include #undef PB_DS_DATA_TRUE_INDICATOR #undef PB_DS_V2F #undef PB_DS_V2S #undef PB_DS_EP2VP #define PB_DS_DATA_FALSE_INDICATOR #define PB_DS_V2F(X) (X) #define PB_DS_V2S(X) Mapped_Data() #define PB_DS_EP2VP(X)& ((X)->m_value.first) #include #include #include #include #include #include #include #include #undef PB_DS_DATA_FALSE_INDICATOR #undef PB_DS_V2F #undef PB_DS_V2S #undef PB_DS_EP2VP #undef PB_DS_CHECK_KEY_DOES_NOT_EXIST #undef PB_DS_CHECK_KEY_EXISTS #undef PB_DS_DEBUG_VERIFY #undef PB_DS_ASSERT_VALID namespace __gnu_pbds { namespace detail { /// Specialization for list-update map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef lu_map type; }; /// Specialization for list-update set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef lu_set type; }; /// Specialization for PATRICIA trie map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: typedef pat_trie_map type; }; /// Specialization for PATRICIA trie set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef pat_trie_set type; }; /// Specialization for R-B tree map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef rb_tree_map type; }; /// Specialization for R-B tree set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: typedef rb_tree_set type; }; /// Specialization splay tree map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef splay_tree_map type; }; /// Specialization splay tree set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef splay_tree_set type; }; /// Specialization ordered-vector tree map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef ov_tree_map type; }; /// Specialization ordered-vector tree set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef ov_tree_set type; }; /// Specialization colision-chaining hash map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; typedef __gnu_cxx::typelist::at_index at2; typedef typename at2::type at2t; typedef __gnu_cxx::typelist::at_index at3; typedef typename at3::type at3t; typedef __gnu_cxx::typelist::at_index at4; typedef typename at4::type at4t; public: /// Dispatched type. typedef cc_ht_map type; }; /// Specialization colision-chaining hash set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; typedef __gnu_cxx::typelist::at_index at2; typedef typename at2::type at2t; typedef __gnu_cxx::typelist::at_index at3; typedef typename at3::type at3t; typedef __gnu_cxx::typelist::at_index at4; typedef typename at4::type at4t; public: /// Dispatched type. typedef cc_ht_set type; }; /// Specialization general-probe hash map. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; typedef __gnu_cxx::typelist::at_index at2; typedef typename at2::type at2t; typedef __gnu_cxx::typelist::at_index at3; typedef typename at3::type at3t; typedef __gnu_cxx::typelist::at_index at4; typedef typename at4::type at4t; typedef __gnu_cxx::typelist::at_index at5; typedef typename at5::type at5t; public: /// Dispatched type. typedef gp_ht_map type; }; /// Specialization general-probe hash set. template struct container_base_dispatch { private: typedef __gnu_cxx::typelist::at_index at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index at1; typedef typename at1::type at1t; typedef __gnu_cxx::typelist::at_index at2; typedef typename at2::type at2t; typedef __gnu_cxx::typelist::at_index at3; typedef typename at3::type at3t; typedef __gnu_cxx::typelist::at_index at4; typedef typename at4::type at4t; typedef __gnu_cxx::typelist::at_index at5; typedef typename at5::type at5t; public: /// Dispatched type. typedef gp_ht_set type; }; } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/binomial_heap_/binomial_heap_.hpp000064400000007522152526447520016453 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_.hpp * Contains an implementation class for a binomial heap. */ /* * Binomial heap. * Vuillemin J is the mastah. * Modified from CLRS. */ #include #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ binomial_heap /** * Binomial heap. * * @ingroup heap-detail */ template class binomial_heap : public binomial_heap_base { private: typedef binomial_heap_base base_type; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::node_const_pointer node_const_pointer; public: typedef Value_Type value_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::cmp_fn cmp_fn; typedef typename base_type::allocator_type allocator_type; binomial_heap(); binomial_heap(const Cmp_Fn&); binomial_heap(const binomial_heap&); ~binomial_heap(); protected: #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif }; #include #include #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC } // namespace detail } // namespace __gnu_pbds 8/ext/pb_ds/detail/binomial_heap_/constructors_destructor_fn_imps.hpp000064400000004147152526447520022266 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/binomial_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation for binomial_heap_. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap(const PB_DS_CLASS_C_DEC& other) : base_type(other) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~binomial_heap() { } 8/ext/pb_ds/detail/binomial_heap_/debug_fn_imps.hpp000064400000003551152526447520016324 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/binomial_heap_/debug_fn_imps.hpp * Contains an implementation for binomial_heap_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(true, __file, __line); } #endif 8/ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp000064400000010136152526447520017056 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/rotate_fn_imps.hpp * Contains imps for rotating nodes. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_left(node_pointer p_x) { node_pointer p_y = p_x->m_p_right; p_x->m_p_right = p_y->m_p_left; if (p_y->m_p_left != 0) p_y->m_p_left->m_p_parent = p_x; p_y->m_p_parent = p_x->m_p_parent; if (p_x == m_p_head->m_p_parent) m_p_head->m_p_parent = p_y; else if (p_x == p_x->m_p_parent->m_p_left) p_x->m_p_parent->m_p_left = p_y; else p_x->m_p_parent->m_p_right = p_y; p_y->m_p_left = p_x; p_x->m_p_parent = p_y; PB_DS_ASSERT_NODE_CONSISTENT(p_x) PB_DS_ASSERT_NODE_CONSISTENT(p_y) apply_update(p_x, (node_update* )this); apply_update(p_x->m_p_parent, (node_update* )this); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_right(node_pointer p_x) { node_pointer p_y = p_x->m_p_left; p_x->m_p_left = p_y->m_p_right; if (p_y->m_p_right != 0) p_y->m_p_right->m_p_parent = p_x; p_y->m_p_parent = p_x->m_p_parent; if (p_x == m_p_head->m_p_parent) m_p_head->m_p_parent = p_y; else if (p_x == p_x->m_p_parent->m_p_right) p_x->m_p_parent->m_p_right = p_y; else p_x->m_p_parent->m_p_left = p_y; p_y->m_p_right = p_x; p_x->m_p_parent = p_y; PB_DS_ASSERT_NODE_CONSISTENT(p_x) PB_DS_ASSERT_NODE_CONSISTENT(p_y) apply_update(p_x, (node_update* )this); apply_update(p_x->m_p_parent, (node_update* )this); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_parent(node_pointer p_nd) { node_pointer p_parent = p_nd->m_p_parent; if (p_nd == p_parent->m_p_left) rotate_right(p_parent); else rotate_left(p_parent); _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_parent = p_nd); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == p_parent || p_nd->m_p_right == p_parent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer /*p_nd*/, null_node_update_pointer /*p_update*/) { } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer p_nd, Node_Update_* /*p_update*/) { node_update::operator()(node_iterator(p_nd), node_const_iterator(static_cast(0))); } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: update_to_top(node_pointer p_nd, Node_Update_* p_update) { while (p_nd != m_p_head) { apply_update(p_nd, p_update); p_nd = p_nd->m_p_parent; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_to_top(node_pointer /*p_nd*/, null_node_update_pointer /*p_update*/) { } 8/ext/pb_ds/detail/bin_search_tree_/r_erase_fn_imps.hpp000064400000005535152526447520017207 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/r_erase_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_node(node_pointer p_z) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ONLY(erase_existing(PB_DS_V2F(p_z->m_value));) p_z->~node(); s_node_allocator.deallocate(p_z, 1); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_min_max_for_erased_node(node_pointer p_z) { if (m_size == 1) { m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; return; } if (m_p_head->m_p_left == p_z) { iterator it(p_z); ++it; m_p_head->m_p_left = it.m_p_nd; } else if (m_p_head->m_p_right == p_z) { iterator it(p_z); --it; m_p_head->m_p_right = it.m_p_nd; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) clear_imp(m_p_head->m_p_parent); m_size = 0; initialize(); _GLIBCXX_DEBUG_ONLY(debug_base::clear();) PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { if (p_nd == 0) return; clear_imp(p_nd->m_p_left); clear_imp(p_nd->m_p_right); p_nd->~Node(); s_node_allocator.deallocate(p_nd, 1); } 8/ext/pb_ds/detail/bin_search_tree_/node_iterators.hpp000064400000013555152526447520017076 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/node_iterators.hpp * Contains an implementation class for bin_search_tree_. */ #ifndef PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP #define PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP #include namespace __gnu_pbds { namespace detail { #define PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC \ bin_search_tree_const_node_it_ /// Const node iterator. template class bin_search_tree_const_node_it_ { private: typedef typename _Alloc::template rebind< Node>::other::pointer node_pointer; public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef Const_Iterator value_type; /// Iterator's reference type. typedef Const_Iterator reference; /// Iterator's __const reference type. typedef Const_Iterator const_reference; /// Metadata type. typedef typename Node::metadata_type metadata_type; /// Const metadata reference type. typedef typename _Alloc::template rebind::other::const_reference metadata_const_reference; bin_search_tree_const_node_it_(const node_pointer p_nd = 0) : m_p_nd(const_cast(p_nd)) { } /// Access. const_reference operator*() const { return Const_Iterator(m_p_nd); } /// Metadata access. metadata_const_reference get_metadata() const { return m_p_nd->get_metadata(); } /// Returns the __const node iterator associated with the left node. PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC get_l_child() const { return PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC(m_p_nd->m_p_left); } /// Returns the __const node iterator associated with the right node. PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC get_r_child() const { return PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC(m_p_nd->m_p_right); } /// Compares to a different iterator object. bool operator==(const PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC& other) const { return m_p_nd == other.m_p_nd; } /// Compares (negatively) to a different iterator object. bool operator!=(const PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC& other) const { return m_p_nd != other.m_p_nd; } node_pointer m_p_nd; }; #define PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC \ bin_search_tree_node_it_ /// Node iterator. template class bin_search_tree_node_it_ : public PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC { private: typedef typename _Alloc::template rebind< Node>::other::pointer node_pointer; public: /// Iterator's value type. typedef Iterator value_type; /// Iterator's reference type. typedef Iterator reference; /// Iterator's __const reference type. typedef Iterator const_reference; inline bin_search_tree_node_it_(const node_pointer p_nd = 0) : PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC(const_cast(p_nd)) { } /// Access. Iterator operator*() const { return Iterator(PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd); } /// Returns the node iterator associated with the left node. PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC get_l_child() const { return PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC( PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd->m_p_left); } /// Returns the node iterator associated with the right node. PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC get_r_child() const { return PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC( PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd->m_p_right); } }; #undef PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC #undef PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP 8/ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp000064400000003561152526447520020404 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/policy_access_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() { return (*this); } PB_DS_CLASS_T_DEC const Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() const { return (*this); } 8/ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp000064400000012603152526447520022607 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/constructors_destructor_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_allocator PB_DS_CLASS_C_DEC::s_node_allocator; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_BIN_TREE_NAME() : m_p_head(s_node_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_BIN_TREE_NAME(const Cmp_Fn& r_cmp_fn) : Cmp_Fn(r_cmp_fn), m_p_head(s_node_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_BIN_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : Cmp_Fn(r_cmp_fn), node_update(r_node_update), m_p_head(s_node_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_BIN_TREE_NAME(const PB_DS_CLASS_C_DEC& other) : #ifdef _GLIBCXX_DEBUG debug_base(other), #endif #ifdef PB_DS_TREE_TRACE PB_DS_TREE_TRACE_BASE_C_DEC(other), #endif Cmp_Fn(other), node_update(other), m_p_head(s_node_allocator.allocate(1)), m_size(0) { initialize(); m_size = other.m_size; PB_DS_STRUCT_ONLY_ASSERT_VALID(other) __try { m_p_head->m_p_parent = recursive_copy_node(other.m_p_head->m_p_parent); if (m_p_head->m_p_parent != 0) m_p_head->m_p_parent->m_p_parent = m_p_head; m_size = other.m_size; initialize_min_max(); } __catch(...) { _GLIBCXX_DEBUG_ONLY(debug_base::clear();) s_node_allocator.deallocate(m_p_head, 1); __throw_exception_again; } PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) value_swap(other); std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);) std::swap(m_p_head, other.m_p_head); std::swap(m_size, other.m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_BIN_TREE_NAME() { clear(); s_node_allocator.deallocate(m_p_head, 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { m_p_head->m_p_parent = 0; m_p_head->m_p_left = m_p_head; m_p_head->m_p_right = m_p_head; m_size = 0; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: recursive_copy_node(const node_pointer p_nd) { if (p_nd == 0) return (0); node_pointer p_ret = s_node_allocator.allocate(1); __try { new (p_ret) node(*p_nd); } __catch(...) { s_node_allocator.deallocate(p_ret, 1); __throw_exception_again; } p_ret->m_p_left = p_ret->m_p_right = 0; __try { p_ret->m_p_left = recursive_copy_node(p_nd->m_p_left); p_ret->m_p_right = recursive_copy_node(p_nd->m_p_right); } __catch(...) { clear_imp(p_ret); __throw_exception_again; } if (p_ret->m_p_left != 0) p_ret->m_p_left->m_p_parent = p_ret; if (p_ret->m_p_right != 0) p_ret->m_p_right->m_p_parent = p_ret; PB_DS_ASSERT_NODE_CONSISTENT(p_ret) return p_ret; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize_min_max() { if (m_p_head->m_p_parent == 0) { m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; return; } { node_pointer p_min = m_p_head->m_p_parent; while (p_min->m_p_left != 0) p_min = p_min->m_p_left; m_p_head->m_p_left = p_min; } { node_pointer p_max = m_p_head->m_p_parent; while (p_max->m_p_right != 0) p_max = p_max->m_p_right; m_p_head->m_p_right = p_max; } } 8/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp000064400000004040152526447520016510 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/info_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (m_size == 0); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return (m_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return (s_node_allocator.max_size()); } 8/ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp000064400000011107152526447520016477 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/find_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: lower_bound(key_const_reference r_key) const { node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) p_nd = p_nd->m_p_right; else { p_pot = p_nd; p_nd = p_nd->m_p_left; } return iterator(p_pot); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: lower_bound(key_const_reference r_key) { node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) p_nd = p_nd->m_p_right; else { p_pot = p_nd; p_nd = p_nd->m_p_left; } return iterator(p_pot); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: upper_bound(key_const_reference r_key) const { node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; return const_iterator(p_pot); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: upper_bound(key_const_reference r_key) { node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; return point_iterator(p_pot); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; node_pointer ret = p_pot; if (p_pot != m_p_head) { const bool __cmp = Cmp_Fn::operator()(r_key, PB_DS_V2F(p_pot->m_value)); if (__cmp) ret = m_p_head; } return point_iterator(ret); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; node_pointer ret = p_pot; if (p_pot != m_p_head) { const bool __cmp = Cmp_Fn::operator()(r_key, PB_DS_V2F(p_pot->m_value)); if (__cmp) ret = m_p_head; } return point_const_iterator(ret); } 8/ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hpp000064400000006673152526447520017607 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/iterators_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { return (iterator(m_p_head->m_p_left)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { return (const_iterator(m_p_head->m_p_left)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return (iterator(m_p_head)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return (const_iterator(m_p_head)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: rbegin() const { return (const_reverse_iterator(m_p_head->m_p_right)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: rbegin() { return (reverse_iterator(m_p_head->m_p_right)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: rend() { return (reverse_iterator(m_p_head)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: rend() const { return (const_reverse_iterator(m_p_head)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_begin() const { return (node_const_iterator(m_p_head->m_p_parent)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_begin() { return (node_iterator(m_p_head->m_p_parent)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_end() const { return (node_const_iterator(0)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_end() { return (node_iterator(0)); } 8/ext/pb_ds/detail/bin_search_tree_/point_iterators.hpp000064400000021401152526447520017267 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/point_iterators.hpp * Contains an implementation class for bin_search_tree_. */ #ifndef PB_DS_BIN_SEARCH_TREE_FIND_ITERATORS_HPP #define PB_DS_BIN_SEARCH_TREE_FIND_ITERATORS_HPP #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_TREE_CONST_IT_C_DEC \ bin_search_tree_const_it_< \ Node_Pointer, \ Value_Type, \ Pointer, \ Const_Pointer, \ Reference, \ Const_Reference, \ Is_Forward_Iterator, \ _Alloc> #define PB_DS_TREE_CONST_ODIR_IT_C_DEC \ bin_search_tree_const_it_< \ Node_Pointer, \ Value_Type, \ Pointer, \ Const_Pointer, \ Reference, \ Const_Reference, \ !Is_Forward_Iterator, \ _Alloc> #define PB_DS_TREE_IT_C_DEC \ bin_search_tree_it_< \ Node_Pointer, \ Value_Type, \ Pointer, \ Const_Pointer, \ Reference, \ Const_Reference, \ Is_Forward_Iterator, \ _Alloc> #define PB_DS_TREE_ODIR_IT_C_DEC \ bin_search_tree_it_< \ Node_Pointer, \ Value_Type, \ Pointer, \ Const_Pointer, \ Reference, \ Const_Reference, \ !Is_Forward_Iterator, \ _Alloc> /// Const iterator. template class bin_search_tree_const_it_ { public: typedef std::bidirectional_iterator_tag iterator_category; typedef typename _Alloc::difference_type difference_type; typedef Value_Type value_type; typedef Pointer pointer; typedef Const_Pointer const_pointer; typedef Reference reference; typedef Const_Reference const_reference; inline bin_search_tree_const_it_(const Node_Pointer p_nd = 0) : m_p_nd(const_cast(p_nd)) { } inline bin_search_tree_const_it_(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) : m_p_nd(other.m_p_nd) { } inline PB_DS_TREE_CONST_IT_C_DEC& operator=(const PB_DS_TREE_CONST_IT_C_DEC& other) { m_p_nd = other.m_p_nd; return *this; } inline PB_DS_TREE_CONST_IT_C_DEC& operator=(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) { m_p_nd = other.m_p_nd; return *this; } inline const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); return &m_p_nd->m_value; } inline const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); return m_p_nd->m_value; } inline bool operator==(const PB_DS_TREE_CONST_IT_C_DEC & other) const { return m_p_nd == other.m_p_nd; } inline bool operator==(const PB_DS_TREE_CONST_ODIR_IT_C_DEC & other) const { return m_p_nd == other.m_p_nd; } inline bool operator!=(const PB_DS_TREE_CONST_IT_C_DEC& other) const { return m_p_nd != other.m_p_nd; } inline bool operator!=(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) const { return m_p_nd != other.m_p_nd; } inline PB_DS_TREE_CONST_IT_C_DEC& operator++() { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); inc(integral_constant()); return *this; } inline PB_DS_TREE_CONST_IT_C_DEC operator++(int) { PB_DS_TREE_CONST_IT_C_DEC ret_it(m_p_nd); operator++(); return ret_it; } inline PB_DS_TREE_CONST_IT_C_DEC& operator--() { dec(integral_constant()); return *this; } inline PB_DS_TREE_CONST_IT_C_DEC operator--(int) { PB_DS_TREE_CONST_IT_C_DEC ret_it(m_p_nd); operator--(); return ret_it; } protected: inline void inc(false_type) { dec(true_type()); } void inc(true_type) { if (m_p_nd->special()&& m_p_nd->m_p_parent->m_p_parent == m_p_nd) { m_p_nd = m_p_nd->m_p_left; return; } if (m_p_nd->m_p_right != 0) { m_p_nd = m_p_nd->m_p_right; while (m_p_nd->m_p_left != 0) m_p_nd = m_p_nd->m_p_left; return; } Node_Pointer p_y = m_p_nd->m_p_parent; while (m_p_nd == p_y->m_p_right) { m_p_nd = p_y; p_y = p_y->m_p_parent; } if (m_p_nd->m_p_right != p_y) m_p_nd = p_y; } inline void dec(false_type) { inc(true_type()); } void dec(true_type) { if (m_p_nd->special() && m_p_nd->m_p_parent->m_p_parent == m_p_nd) { m_p_nd = m_p_nd->m_p_right; return; } if (m_p_nd->m_p_left != 0) { Node_Pointer p_y = m_p_nd->m_p_left; while (p_y->m_p_right != 0) p_y = p_y->m_p_right; m_p_nd = p_y; return; } Node_Pointer p_y = m_p_nd->m_p_parent; while (m_p_nd == p_y->m_p_left) { m_p_nd = p_y; p_y = p_y->m_p_parent; } if (m_p_nd->m_p_left != p_y) m_p_nd = p_y; } public: Node_Pointer m_p_nd; }; /// Iterator. template class bin_search_tree_it_ : public PB_DS_TREE_CONST_IT_C_DEC { public: inline bin_search_tree_it_(const Node_Pointer p_nd = 0) : PB_DS_TREE_CONST_IT_C_DEC((Node_Pointer)p_nd) { } inline bin_search_tree_it_(const PB_DS_TREE_ODIR_IT_C_DEC& other) : PB_DS_TREE_CONST_IT_C_DEC(other.m_p_nd) { } inline PB_DS_TREE_IT_C_DEC& operator=(const PB_DS_TREE_IT_C_DEC& other) { base_it_type::m_p_nd = other.m_p_nd; return *this; } inline PB_DS_TREE_IT_C_DEC& operator=(const PB_DS_TREE_ODIR_IT_C_DEC& other) { base_it_type::m_p_nd = other.m_p_nd; return *this; } inline typename PB_DS_TREE_CONST_IT_C_DEC::pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd != 0); return &base_it_type::m_p_nd->m_value; } inline typename PB_DS_TREE_CONST_IT_C_DEC::reference operator*() const { _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd != 0); return base_it_type::m_p_nd->m_value; } inline PB_DS_TREE_IT_C_DEC& operator++() { PB_DS_TREE_CONST_IT_C_DEC:: operator++(); return *this; } inline PB_DS_TREE_IT_C_DEC operator++(int) { PB_DS_TREE_IT_C_DEC ret_it(base_it_type::m_p_nd); operator++(); return ret_it; } inline PB_DS_TREE_IT_C_DEC& operator--() { PB_DS_TREE_CONST_IT_C_DEC:: operator--(); return *this; } inline PB_DS_TREE_IT_C_DEC operator--(int) { PB_DS_TREE_IT_C_DEC ret_it(base_it_type::m_p_nd); operator--(); return ret_it; } protected: typedef PB_DS_TREE_CONST_IT_C_DEC base_it_type; }; #undef PB_DS_TREE_CONST_IT_C_DEC #undef PB_DS_TREE_CONST_ODIR_IT_C_DEC #undef PB_DS_TREE_IT_C_DEC #undef PB_DS_TREE_ODIR_IT_C_DEC } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hpp000064400000017607152526447520016660 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/debug_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { structure_only_assert_valid(__file, __line); assert_consistent_with_debug_base(__file, __line); assert_size(__file, __line); assert_iterators(__file, __line); if (m_p_head->m_p_parent == 0) { PB_DS_DEBUG_VERIFY(m_size == 0); } else { PB_DS_DEBUG_VERIFY(m_size > 0); } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: structure_only_assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_p_head != 0); if (m_p_head->m_p_parent == 0) { PB_DS_DEBUG_VERIFY(m_p_head->m_p_left == m_p_head); PB_DS_DEBUG_VERIFY(m_p_head->m_p_right == m_p_head); } else { PB_DS_DEBUG_VERIFY(m_p_head->m_p_parent->m_p_parent == m_p_head); PB_DS_DEBUG_VERIFY(m_p_head->m_p_left != m_p_head); PB_DS_DEBUG_VERIFY(m_p_head->m_p_right != m_p_head); } if (m_p_head->m_p_parent != 0) assert_node_consistent(m_p_head->m_p_parent, __file, __line); assert_min(__file, __line); assert_max(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent(const node_pointer p_nd, const char* __file, int __line) const { assert_node_consistent_(p_nd, __file, __line); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_consistent_t PB_DS_CLASS_C_DEC:: assert_node_consistent_(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) return (std::make_pair((const_pointer)0,(const_pointer)0)); assert_node_consistent_with_left(p_nd, __file, __line); assert_node_consistent_with_right(p_nd, __file, __line); const std::pair l_range = assert_node_consistent_(p_nd->m_p_left, __file, __line); if (l_range.second != 0) PB_DS_DEBUG_VERIFY(Cmp_Fn::operator()(PB_DS_V2F(*l_range.second), PB_DS_V2F(p_nd->m_value))); const std::pair r_range = assert_node_consistent_(p_nd->m_p_right, __file, __line); if (r_range.first != 0) PB_DS_DEBUG_VERIFY(Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(*r_range.first))); return std::make_pair((l_range.first != 0) ? l_range.first : &p_nd->m_value, (r_range.second != 0)? r_range.second : &p_nd->m_value); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent_with_left(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd->m_p_left == 0) return; PB_DS_DEBUG_VERIFY(p_nd->m_p_left->m_p_parent == p_nd); PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(p_nd->m_p_left->m_value))); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent_with_right(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd->m_p_right == 0) return; PB_DS_DEBUG_VERIFY(p_nd->m_p_right->m_p_parent == p_nd); PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_p_right->m_value), PB_DS_V2F(p_nd->m_value))); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_min(const char* __file, int __line) const { assert_min_imp(m_p_head->m_p_parent, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_min_imp(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) { PB_DS_DEBUG_VERIFY(m_p_head->m_p_left == m_p_head); return; } if (p_nd->m_p_left == 0) { PB_DS_DEBUG_VERIFY(p_nd == m_p_head->m_p_left); return; } assert_min_imp(p_nd->m_p_left, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_max(const char* __file, int __line) const { assert_max_imp(m_p_head->m_p_parent, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_max_imp(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) { PB_DS_DEBUG_VERIFY(m_p_head->m_p_right == m_p_head); return; } if (p_nd->m_p_right == 0) { PB_DS_DEBUG_VERIFY(p_nd == m_p_head->m_p_right); return; } assert_max_imp(p_nd->m_p_right, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_iterators(const char* __file, int __line) const { size_type iterated_num = 0; const_iterator prev_it = end(); for (const_iterator it = begin(); it != end(); ++it) { ++iterated_num; PB_DS_DEBUG_VERIFY(lower_bound(PB_DS_V2F(*it)).m_p_nd == it.m_p_nd); const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*it)); --upper_bound_it; PB_DS_DEBUG_VERIFY(upper_bound_it.m_p_nd == it.m_p_nd); if (prev_it != end()) PB_DS_DEBUG_VERIFY(Cmp_Fn::operator()(PB_DS_V2F(*prev_it), PB_DS_V2F(*it))); prev_it = it; } PB_DS_DEBUG_VERIFY(iterated_num == m_size); size_type reverse_iterated_num = 0; const_reverse_iterator reverse_prev_it = rend(); for (const_reverse_iterator reverse_it = rbegin(); reverse_it != rend(); ++reverse_it) { ++reverse_iterated_num; PB_DS_DEBUG_VERIFY(lower_bound( PB_DS_V2F(*reverse_it)).m_p_nd == reverse_it.m_p_nd); const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*reverse_it)); --upper_bound_it; PB_DS_DEBUG_VERIFY(upper_bound_it.m_p_nd == reverse_it.m_p_nd); if (reverse_prev_it != rend()) PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(PB_DS_V2F(*reverse_prev_it), PB_DS_V2F(*reverse_it))); reverse_prev_it = reverse_it; } PB_DS_DEBUG_VERIFY(reverse_iterated_num == m_size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_consistent_with_debug_base(const char* __file, int __line) const { debug_base::check_size(m_size, __file, __line); assert_consistent_with_debug_base(m_p_head->m_p_parent, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_consistent_with_debug_base(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) return; debug_base::check_key_exists(PB_DS_V2F(p_nd->m_value), __file, __line); assert_consistent_with_debug_base(p_nd->m_p_left, __file, __line); assert_consistent_with_debug_base(p_nd->m_p_right, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_size(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(recursive_count(m_p_head->m_p_parent) == m_size); } #endif 8/ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp000064400000012551152526447520017067 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/insert_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert_leaf(const_reference r_value) { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) if (m_size == 0) return std::make_pair(insert_imp_empty(r_value), true); node_pointer p_nd = m_p_head->m_p_parent; node_pointer p_pot = m_p_head; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(r_value))) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; if (p_pot == m_p_head) return std::make_pair(insert_leaf_new(r_value, m_p_head->m_p_right, false), true); if (!Cmp_Fn::operator()(PB_DS_V2F(r_value), PB_DS_V2F(p_pot->m_value))) { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(r_value)) return std::make_pair(p_pot, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_value)) p_nd = p_pot->m_p_left; if (p_nd == 0) return std::make_pair(insert_leaf_new(r_value, p_pot, true), true); while (p_nd->m_p_right != 0) p_nd = p_nd->m_p_right; return std::make_pair(insert_leaf_new(r_value, p_nd, false), true); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: insert_leaf_new(const_reference r_value, node_pointer p_nd, bool left_nd) { node_pointer p_new_nd = get_new_node_for_leaf_insert(r_value, traits_base::m_no_throw_copies_indicator); if (left_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == 0); _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(r_value), PB_DS_V2F(p_nd->m_value))); p_nd->m_p_left = p_new_nd; if (m_p_head->m_p_left == p_nd) m_p_head->m_p_left = p_new_nd; } else { _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_right == 0); _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(r_value))); p_nd->m_p_right = p_new_nd; if (m_p_head->m_p_right == p_nd) m_p_head->m_p_right = p_new_nd; } p_new_nd->m_p_parent = p_nd; p_new_nd->m_p_left = p_new_nd->m_p_right = 0; PB_DS_ASSERT_NODE_CONSISTENT(p_nd) update_to_top(p_new_nd, (node_update* )this); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_value));) return iterator(p_new_nd); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: insert_imp_empty(const_reference r_value) { node_pointer p_new_node = get_new_node_for_leaf_insert(r_value, traits_base::m_no_throw_copies_indicator); m_p_head->m_p_left = m_p_head->m_p_right = m_p_head->m_p_parent = p_new_node; p_new_node->m_p_parent = m_p_head; p_new_node->m_p_left = p_new_node->m_p_right = 0; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_value));) update_to_top(m_p_head->m_p_parent, (node_update*)this); return iterator(p_new_node); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_leaf_insert(const_reference r_val, false_type) { node_pointer p_new_nd = s_node_allocator.allocate(1); cond_dealtor_t cond(p_new_nd); new (const_cast(static_cast(&p_new_nd->m_value))) typename node::value_type(r_val); cond.set_no_action(); p_new_nd->m_p_left = p_new_nd->m_p_right = 0; ++m_size; return p_new_nd; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_leaf_insert(const_reference r_val, true_type) { node_pointer p_new_nd = s_node_allocator.allocate(1); new (const_cast(static_cast(&p_new_nd->m_value))) typename node::value_type(r_val); p_new_nd->m_p_left = p_new_nd->m_p_right = 0; ++m_size; return p_new_nd; } 8/ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hpp000064400000005547152526447520016671 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/erase_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_node(node_pointer p_z) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_z->m_value));) p_z->~node(); s_node_allocator.deallocate(p_z, 1); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_min_max_for_erased_node(node_pointer p_z) { if (m_size == 1) { m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; return; } if (m_p_head->m_p_left == p_z) { iterator it(p_z); ++it; m_p_head->m_p_left = it.m_p_nd; } else if (m_p_head->m_p_right == p_z) { iterator it(p_z); --it; m_p_head->m_p_right = it.m_p_nd; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) clear_imp(m_p_head->m_p_parent); m_size = 0; initialize(); _GLIBCXX_DEBUG_ONLY(debug_base::clear();) PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { if (p_nd == 0) return; clear_imp(p_nd->m_p_left); clear_imp(p_nd->m_p_right); p_nd->~node(); s_node_allocator.deallocate(p_nd, 1); } 8/ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp000064400000030203152526447520017315 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/bin_search_tree_.hpp * Contains an implementation class for binary search tree. */ #include #include #include #include #include #include #include #ifdef _GLIBCXX_DEBUG #include #endif #include #include #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_BIN_TREE_NAME bin_search_tree_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_BIN_TREE_NAME bin_search_tree_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_BIN_TREE_NAME #define PB_DS_BIN_TREE_TRAITS_BASE \ types_traits #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base, \ typename _Alloc::template rebind::other::const_reference> #endif #ifdef PB_DS_TREE_TRACE #define PB_DS_TREE_TRACE_BASE_C_DEC \ tree_trace_base #endif /* * @brief Binary search tree (BST). * * This implementation uses an idea from the SGI STL (using a @a * header node which is needed for efficient iteration). */ template class PB_DS_BIN_TREE_NAME : #ifdef _GLIBCXX_DEBUG public PB_DS_DEBUG_MAP_BASE_C_DEC, #endif #ifdef PB_DS_TREE_TRACE public PB_DS_TREE_TRACE_BASE_C_DEC, #endif public Cmp_Fn, public PB_DS_BIN_TREE_TRAITS_BASE, public Node_And_It_Traits::node_update { typedef Node_And_It_Traits traits_type; protected: typedef PB_DS_BIN_TREE_TRAITS_BASE traits_base; typedef typename _Alloc::template rebind::other node_allocator; typedef typename node_allocator::value_type node; typedef typename node_allocator::pointer node_pointer; typedef typename traits_type::null_node_update_pointer null_node_update_pointer; private: typedef cond_dealtor cond_dealtor_t; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif public: typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; #endif typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; typedef typename traits_type::point_const_iterator point_const_iterator; typedef point_const_iterator const_iterator; typedef typename traits_type::point_iterator point_iterator; typedef point_iterator iterator; typedef typename traits_type::const_reverse_iterator const_reverse_iterator; typedef typename traits_type::reverse_iterator reverse_iterator; typedef typename traits_type::node_const_iterator node_const_iterator; typedef typename traits_type::node_iterator node_iterator; typedef typename traits_type::node_update node_update; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; PB_DS_BIN_TREE_NAME(); PB_DS_BIN_TREE_NAME(const Cmp_Fn&); PB_DS_BIN_TREE_NAME(const Cmp_Fn&, const node_update&); PB_DS_BIN_TREE_NAME(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); ~PB_DS_BIN_TREE_NAME(); inline bool empty() const; inline size_type size() const; inline size_type max_size() const; Cmp_Fn& get_cmp_fn(); const Cmp_Fn& get_cmp_fn() const; inline point_iterator lower_bound(key_const_reference); inline point_const_iterator lower_bound(key_const_reference) const; inline point_iterator upper_bound(key_const_reference); inline point_const_iterator upper_bound(key_const_reference) const; inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; inline reverse_iterator rbegin(); inline const_reverse_iterator rbegin() const; inline reverse_iterator rend(); inline const_reverse_iterator rend() const; /// Returns a const node_iterator corresponding to the node at the /// root of the tree. inline node_const_iterator node_begin() const; /// Returns a node_iterator corresponding to the node at the /// root of the tree. inline node_iterator node_begin(); /// Returns a const node_iterator corresponding to a node just /// after a leaf of the tree. inline node_const_iterator node_end() const; /// Returns a node_iterator corresponding to a node just /// after a leaf of the tree. inline node_iterator node_end(); void clear(); protected: void value_swap(PB_DS_CLASS_C_DEC&); void initialize_min_max(); inline iterator insert_imp_empty(const_reference); inline iterator insert_leaf_new(const_reference, node_pointer, bool); inline node_pointer get_new_node_for_leaf_insert(const_reference, false_type); inline node_pointer get_new_node_for_leaf_insert(const_reference, true_type); inline void actual_erase_node(node_pointer); inline std::pair erase(node_pointer); inline void update_min_max_for_erased_node(node_pointer); static void clear_imp(node_pointer); inline std::pair insert_leaf(const_reference); inline void rotate_left(node_pointer); inline void rotate_right(node_pointer); inline void rotate_parent(node_pointer); inline void apply_update(node_pointer, null_node_update_pointer); template inline void apply_update(node_pointer, Node_Update_*); inline void update_to_top(node_pointer, null_node_update_pointer); template inline void update_to_top(node_pointer, Node_Update_*); bool join_prep(PB_DS_CLASS_C_DEC&); void join_finish(PB_DS_CLASS_C_DEC&); bool split_prep(key_const_reference, PB_DS_CLASS_C_DEC&); void split_finish(PB_DS_CLASS_C_DEC&); size_type recursive_count(node_pointer) const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void structure_only_assert_valid(const char*, int) const; void assert_node_consistent(const node_pointer, const char*, int) const; #endif private: #ifdef _GLIBCXX_DEBUG void assert_iterators(const char*, int) const; void assert_consistent_with_debug_base(const char*, int) const; void assert_node_consistent_with_left(const node_pointer, const char*, int) const; void assert_node_consistent_with_right(const node_pointer, const char*, int) const; void assert_consistent_with_debug_base(const node_pointer, const char*, int) const; void assert_min(const char*, int) const; void assert_min_imp(const node_pointer, const char*, int) const; void assert_max(const char*, int) const; void assert_max_imp(const node_pointer, const char*, int) const; void assert_size(const char*, int) const; typedef std::pair node_consistent_t; node_consistent_t assert_node_consistent_(const node_pointer, const char*, int) const; #endif void initialize(); node_pointer recursive_copy_node(const node_pointer); protected: node_pointer m_p_head; size_type m_size; static node_allocator s_node_allocator; }; #define PB_DS_STRUCT_ONLY_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.structure_only_assert_valid(__FILE__, __LINE__);) #define PB_DS_ASSERT_NODE_CONSISTENT(_Node) \ _GLIBCXX_DEBUG_ONLY(assert_node_consistent(_Node, __FILE__, __LINE__);) #include #include #include #include #include #include #include #include #include #include #undef PB_DS_ASSERT_NODE_CONSISTENT #undef PB_DS_STRUCT_ONLY_ASSERT_VALID #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_BIN_TREE_NAME #undef PB_DS_BIN_TREE_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #ifdef PB_DS_TREE_TRACE #undef PB_DS_TREE_TRACE_BASE_C_DEC #endif } // namespace detail } // namespace __gnu_pbds 8/ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp000064400000007647152526447520017747 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/split_join_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: join_prep(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (other.m_size == 0) return false; if (m_size == 0) { value_swap(other); return false; } const bool greater = Cmp_Fn::operator()(PB_DS_V2F(m_p_head->m_p_right->m_value), PB_DS_V2F(other.m_p_head->m_p_left->m_value)); const bool lesser = Cmp_Fn::operator()(PB_DS_V2F(other.m_p_head->m_p_right->m_value), PB_DS_V2F(m_p_head->m_p_left->m_value)); if (!greater && !lesser) __throw_join_error(); if (lesser) value_swap(other); m_size += other.m_size; _GLIBCXX_DEBUG_ONLY(debug_base::join(other);) return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join_finish(PB_DS_CLASS_C_DEC& other) { initialize_min_max(); other.initialize(); } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: split_prep(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) other.clear(); if (m_size == 0) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return false; } if (Cmp_Fn::operator()(r_key, PB_DS_V2F(m_p_head->m_p_left->m_value))) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return false; } if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(m_p_head->m_p_right->m_value))) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return false; } if (m_size == 1) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return false; } _GLIBCXX_DEBUG_ONLY(debug_base::split(r_key,(Cmp_Fn& )(*this), other);) return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split_finish(PB_DS_CLASS_C_DEC& other) { other.initialize_min_max(); other.m_size = std::distance(other.begin(), other.end()); m_size -= other.m_size; initialize_min_max(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: recursive_count(node_pointer p) const { if (p == 0) return 0; return 1 + recursive_count(p->m_p_left) + recursive_count(p->m_p_right); } 8/ext/pb_ds/detail/bin_search_tree_/traits.hpp000064400000014352152526447520015357 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/traits.hpp * Contains an implementation for bin_search_tree_. */ #ifndef PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP #define PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP #include #include namespace __gnu_pbds { namespace detail { /// Binary search tree traits, primary template /// @ingroup traits template class Node_Update, class Node, typename _Alloc> struct bin_search_tree_traits { private: typedef types_traits type_traits; public: typedef Node node; typedef bin_search_tree_const_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, true, _Alloc> point_const_iterator; typedef bin_search_tree_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, true, _Alloc> point_iterator; typedef bin_search_tree_const_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, false, _Alloc> const_reverse_iterator; typedef bin_search_tree_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, false, _Alloc> reverse_iterator; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef bin_search_tree_const_node_it_< Node, point_const_iterator, point_iterator, _Alloc> node_const_iterator; typedef bin_search_tree_node_it_< Node, point_const_iterator, point_iterator, _Alloc> node_iterator; typedef Node_Update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc> node_update; typedef __gnu_pbds::null_node_update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc>* null_node_update_pointer; }; /// Specialization. /// @ingroup traits template class Node_Update, class Node, typename _Alloc> struct bin_search_tree_traits { private: typedef types_traits type_traits; public: typedef Node node; typedef bin_search_tree_const_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, true, _Alloc> point_const_iterator; typedef point_const_iterator point_iterator; typedef bin_search_tree_const_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, false, _Alloc> const_reverse_iterator; typedef const_reverse_iterator reverse_iterator; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef bin_search_tree_const_node_it_< Node, point_const_iterator, point_iterator, _Alloc> node_const_iterator; typedef node_const_iterator node_iterator; typedef Node_Update node_update; typedef __gnu_pbds::null_node_update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc>* null_node_update_pointer; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP 8/ext/pb_ds/detail/resize_policy/sample_resize_trigger.hpp000064400000007512152526447520020043 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_resize_trigger.hpp * Contains a sample resize trigger policy class. */ #ifndef PB_DS_SAMPLE_RESIZE_TRIGGER_HPP #define PB_DS_SAMPLE_RESIZE_TRIGGER_HPP namespace __gnu_pbds { /// A sample resize trigger policy. class sample_resize_trigger { public: /// Size type. typedef std::size_t size_type; /// Default constructor. sample_resize_trigger(); /// Copy constructor. sample_range_hashing(const sample_resize_trigger&); /// Swaps content. inline void swap(sample_resize_trigger&); protected: /// Notifies a search started. inline void notify_insert_search_start(); /// Notifies a search encountered a collision. inline void notify_insert_search_collision(); /// Notifies a search ended. inline void notify_insert_search_end(); /// Notifies a search started. inline void notify_find_search_start(); /// Notifies a search encountered a collision. inline void notify_find_search_collision(); /// Notifies a search ended. inline void notify_find_search_end(); /// Notifies a search started. inline void notify_erase_search_start(); /// Notifies a search encountered a collision. inline void notify_erase_search_collision(); /// Notifies a search ended. inline void notify_erase_search_end(); /// Notifies an element was inserted. the total number of entries in /// the table is num_entries. inline void notify_inserted(size_type num_entries); /// Notifies an element was erased. inline void notify_erased(size_type num_entries); /// Notifies the table was cleared. void notify_cleared(); /// Notifies the table was resized as a result of this object's /// signifying that a resize is needed. void notify_resized(size_type new_size); /// Notifies the table was resized externally. void notify_externally_resized(size_type new_size); /// Queries whether a resize is needed. inline bool is_resize_needed() const; /// Queries whether a grow is needed. inline bool is_grow_needed(size_type size, size_type num_entries) const; private: /// Resizes to new_size. virtual void do_resize(size_type); }; } #endif 8/ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp000064400000005324152526447520022264 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_exponential_size_policy_imp.hpp * Contains a resize size policy implementation. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_exponential_size_policy(size_type start_size, size_type grow_factor) : m_start_size(start_size), m_grow_factor(grow_factor) { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_start_size, other.m_start_size); std::swap(m_grow_factor, other.m_grow_factor); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_nearest_larger_size(size_type size) const { size_type ret = m_start_size; while (ret <= size) { const size_type next_ret = ret* m_grow_factor; if (next_ret < ret) __throw_insert_error(); ret = next_ret; } return ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_nearest_smaller_size(size_type size) const { size_type ret = m_start_size; while (true) { const size_type next_ret = ret* m_grow_factor; if (next_ret < ret) __throw_resize_error(); if (next_ret >= size) return (ret); ret = next_ret; } return ret; } 8/ext/pb_ds/detail/resize_policy/sample_size_policy.hpp000064400000004573152526447520017354 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_size_policy.hpp * Contains a sample size resize-policy. */ #ifndef PB_DS_SAMPLE_SIZE_POLICY_HPP #define PB_DS_SAMPLE_SIZE_POLICY_HPP namespace __gnu_pbds { /// A sample size policy. class sample_size_policy { public: /// Size type. typedef std::size_t size_type; /// Default constructor. sample_size_policy(); /// Copy constructor. sample_range_hashing(const sample_size_policy&); /// Swaps content. inline void swap(sample_size_policy& other); protected: /// Given a __size size, returns a __size that is larger. inline size_type get_nearest_larger_size(size_type size) const; /// Given a __size size, returns a __size that is smaller. inline size_type get_nearest_smaller_size(size_type size) const; }; } #endif 8/ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp000064400000011443152526447520025072 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_max_collision_check_resize_trigger_imp.hpp * Contains a resize trigger implementation. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: cc_hash_max_collision_check_resize_trigger(float load) : m_load(load), m_size(0), m_num_col(0), m_max_col(0), m_resize_needed(false) { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_start() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_collision() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_end() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_start() { m_num_col = 0; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_collision() { ++m_num_col; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_end() { calc_resize_needed(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_start() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_collision() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_end() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_inserted(size_type) { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erased(size_type) { m_resize_needed = true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_cleared() { m_resize_needed = false; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_resize_needed() const { return m_resize_needed; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_grow_needed(size_type /*size*/, size_type /*num_used_e*/) const { return m_num_col >= m_max_col; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type new_size) { m_size = new_size; #ifdef PB_DS_HT_MAP_RESIZE_TRACE_ std::cerr << "chmccrt::notify_resized " << static_cast(new_size) << std::endl; #endif calc_max_num_coll(); calc_resize_needed(); m_num_col = 0; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: calc_max_num_coll() { // max_col <-- \sqrt{2 load \ln( 2 m \ln( m ) ) } const double ln_arg = 2 * m_size * std::log(double(m_size)); m_max_col = size_type(std::ceil(std::sqrt(2 * m_load * std::log(ln_arg)))); #ifdef PB_DS_HT_MAP_RESIZE_TRACE_ std::cerr << "chmccrt::calc_max_num_coll " << static_cast(m_size) << " " << static_cast(m_max_col) << std::endl; #endif } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_externally_resized(size_type new_size) { notify_resized(new_size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_load, other.m_load); std::swap(m_size, other.m_size); std::swap(m_num_col, other.m_num_col); std::swap(m_max_col, other.m_max_col); std::swap(m_resize_needed, other.m_resize_needed); } PB_DS_CLASS_T_DEC inline float PB_DS_CLASS_C_DEC:: get_load() const { PB_DS_STATIC_ASSERT(access, external_load_access); return m_load; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: calc_resize_needed() { m_resize_needed = m_resize_needed || m_num_col >= m_max_col; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: set_load(float load) { PB_DS_STATIC_ASSERT(access, external_load_access); m_load = load; calc_max_num_coll(); calc_resize_needed(); } 8/ext/pb_ds/detail/resize_policy/sample_resize_policy.hpp000064400000006772152526447520017706 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_resize_policy.hpp * Contains a sample resize policy for hash tables. */ #ifndef PB_DS_SAMPLE_RESIZE_POLICY_HPP #define PB_DS_SAMPLE_RESIZE_POLICY_HPP namespace __gnu_pbds { /// A sample resize policy. class sample_resize_policy { public: /// Size type. typedef std::size_t size_type; /// Default constructor. sample_resize_policy(); /// Copy constructor. sample_range_hashing(const sample_resize_policy& other); /// Swaps content. inline void swap(sample_resize_policy& other); protected: /// Notifies a search started. inline void notify_insert_search_start(); /// Notifies a search encountered a collision. inline void notify_insert_search_collision(); /// Notifies a search ended. inline void notify_insert_search_end(); /// Notifies a search started. inline void notify_find_search_start(); /// Notifies a search encountered a collision. inline void notify_find_search_collision(); /// Notifies a search ended. inline void notify_find_search_end(); /// Notifies a search started. inline void notify_erase_search_start(); /// Notifies a search encountered a collision. inline void notify_erase_search_collision(); /// Notifies a search ended. inline void notify_erase_search_end(); /// Notifies an element was inserted. inline void notify_inserted(size_type num_e); /// Notifies an element was erased. inline void notify_erased(size_type num_e); /// Notifies the table was cleared. void notify_cleared(); /// Notifies the table was resized to new_size. void notify_resized(size_type new_size); /// Queries whether a resize is needed. inline bool is_resize_needed() const; /// Queries what the new size should be. size_type get_new_size(size_type size, size_type num_used_e) const; }; } #endif 8/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp000064400000017110152526447520022501 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_load_check_resize_trigger_imp.hpp * Contains a resize trigger implementation. */ #define PB_DS_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);) PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_load_check_resize_trigger(float load_min, float load_max) : m_load_min(load_min), m_load_max(load_max), m_next_shrink_size(0), m_next_grow_size(0), m_resize_needed(false) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_start() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_collision() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_end() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_start() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_collision() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_end() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_start() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_collision() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_end() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_inserted(size_type num_entries) { m_resize_needed = (num_entries >= m_next_grow_size); size_base::set_size(num_entries); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erased(size_type num_entries) { size_base::set_size(num_entries); m_resize_needed = num_entries <= m_next_shrink_size; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_resize_needed() const { PB_DS_ASSERT_VALID((*this)) return m_resize_needed; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_grow_needed(size_type /*size*/, size_type num_entries) const { _GLIBCXX_DEBUG_ASSERT(m_resize_needed); return num_entries >= m_next_grow_size; } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~hash_load_check_resize_trigger() { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type new_size) { m_resize_needed = false; m_next_grow_size = size_type(m_load_max * new_size - 1); m_next_shrink_size = size_type(m_load_min * new_size); #ifdef PB_DS_HT_MAP_RESIZE_TRACE_ std::cerr << "hlcrt::notify_resized " << std::endl << "1 " << new_size << std::endl << "2 " << m_load_min << std::endl << "3 " << m_load_max << std::endl << "4 " << m_next_shrink_size << std::endl << "5 " << m_next_grow_size << std::endl; #endif PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_externally_resized(size_type new_size) { m_resize_needed = false; size_type new_grow_size = size_type(m_load_max * new_size - 1); size_type new_shrink_size = size_type(m_load_min * new_size); #ifdef PB_DS_HT_MAP_RESIZE_TRACE_ std::cerr << "hlcrt::notify_externally_resized " << std::endl << "1 " << new_size << std::endl << "2 " << m_load_min << std::endl << "3 " << m_load_max << std::endl << "4 " << m_next_shrink_size << std::endl << "5 " << m_next_grow_size << std::endl << "6 " << new_shrink_size << std::endl << "7 " << new_grow_size << std::endl; #endif if (new_grow_size >= m_next_grow_size) { _GLIBCXX_DEBUG_ASSERT(new_shrink_size >= m_next_shrink_size); m_next_grow_size = new_grow_size; } else { _GLIBCXX_DEBUG_ASSERT(new_shrink_size <= m_next_shrink_size); m_next_shrink_size = new_shrink_size; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_cleared() { PB_DS_ASSERT_VALID((*this)) size_base::set_size(0); m_resize_needed = (0 < m_next_shrink_size); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) size_base::swap(other); std::swap(m_load_min, other.m_load_min); std::swap(m_load_max, other.m_load_max); std::swap(m_resize_needed, other.m_resize_needed); std::swap(m_next_grow_size, other.m_next_grow_size); std::swap(m_next_shrink_size, other.m_next_shrink_size); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: get_loads() const { PB_DS_STATIC_ASSERT(access, external_load_access); return std::make_pair(m_load_min, m_load_max); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: set_loads(std::pair load_pair) { PB_DS_STATIC_ASSERT(access, external_load_access); const float old_load_min = m_load_min; const float old_load_max = m_load_max; const size_type old_next_shrink_size = m_next_shrink_size; const size_type old_next_grow_size = m_next_grow_size; const bool old_resize_needed = m_resize_needed; __try { m_load_min = load_pair.first; m_load_max = load_pair.second; do_resize(static_cast(size_base::get_size() / ((m_load_min + m_load_max) / 2))); } __catch(...) { m_load_min = old_load_min; m_load_max = old_load_max; m_next_shrink_size = old_next_shrink_size; m_next_grow_size = old_next_grow_size; m_resize_needed = old_resize_needed; __throw_exception_again; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: do_resize(size_type) { std::abort(); } #ifdef _GLIBCXX_DEBUG # define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_load_max > m_load_min); PB_DS_DEBUG_VERIFY(m_next_grow_size >= m_next_shrink_size); } # undef PB_DS_DEBUG_VERIFY #endif #undef PB_DS_ASSERT_VALID 8/ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp000064400000014213152526447520022062 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_standard_resize_policy_imp.hpp * Contains a resize policy implementation. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_standard_resize_policy() : m_size(Size_Policy::get_nearest_larger_size(1)) { trigger_policy_base::notify_externally_resized(m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_standard_resize_policy(const Size_Policy& r_size_policy) : Size_Policy(r_size_policy), m_size(Size_Policy::get_nearest_larger_size(1)) { trigger_policy_base::notify_externally_resized(m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_standard_resize_policy(const Size_Policy& r_size_policy, const Trigger_Policy& r_trigger_policy) : Size_Policy(r_size_policy), Trigger_Policy(r_trigger_policy), m_size(Size_Policy::get_nearest_larger_size(1)) { trigger_policy_base::notify_externally_resized(m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~hash_standard_resize_policy() { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { trigger_policy_base::swap(other); size_policy_base::swap(other); std::swap(m_size, other.m_size); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_start() { trigger_policy_base::notify_find_search_start(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_collision() { trigger_policy_base::notify_find_search_collision(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_end() { trigger_policy_base::notify_find_search_end(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_start() { trigger_policy_base::notify_insert_search_start(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_collision() { trigger_policy_base::notify_insert_search_collision(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_end() { trigger_policy_base::notify_insert_search_end(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_start() { trigger_policy_base::notify_erase_search_start(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_collision() { trigger_policy_base::notify_erase_search_collision(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_end() { trigger_policy_base::notify_erase_search_end(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_inserted(size_type num_e) { trigger_policy_base::notify_inserted(num_e); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erased(size_type num_e) { trigger_policy_base::notify_erased(num_e); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_cleared() { trigger_policy_base::notify_cleared(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_resize_needed() const { return trigger_policy_base::is_resize_needed(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_new_size(size_type size, size_type num_used_e) const { if (trigger_policy_base::is_grow_needed(size, num_used_e)) return size_policy_base::get_nearest_larger_size(size); return size_policy_base::get_nearest_smaller_size(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type new_size) { trigger_policy_base::notify_resized(new_size); m_size = new_size; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_actual_size() const { PB_DS_STATIC_ASSERT(access, external_size_access); return m_size; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize(size_type new_size) { PB_DS_STATIC_ASSERT(access, external_size_access); size_type actual_size = size_policy_base::get_nearest_larger_size(1); while (actual_size < new_size) { const size_type pot = size_policy_base::get_nearest_larger_size(actual_size); if (pot == actual_size && pot < new_size) __throw_resize_error(); actual_size = pot; } if (actual_size > 0) --actual_size; const size_type old_size = m_size; __try { do_resize(actual_size - 1); } __catch(insert_error& ) { m_size = old_size; __throw_resize_error(); } __catch(...) { m_size = old_size; __throw_exception_again; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: do_resize(size_type) { // Do nothing } PB_DS_CLASS_T_DEC Trigger_Policy& PB_DS_CLASS_C_DEC:: get_trigger_policy() { return *this; } PB_DS_CLASS_T_DEC const Trigger_Policy& PB_DS_CLASS_C_DEC:: get_trigger_policy() const { return *this; } PB_DS_CLASS_T_DEC Size_Policy& PB_DS_CLASS_C_DEC:: get_size_policy() { return *this; } PB_DS_CLASS_T_DEC const Size_Policy& PB_DS_CLASS_C_DEC:: get_size_policy() const { return *this; } 8/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp000064400000013773152526447520021061 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_prime_size_policy_imp.hpp * Contains a resize size policy implementation. */ #pragma GCC system_header namespace detail { enum { num_distinct_sizes_32_bit = 30, num_distinct_sizes_64_bit = 62, num_distinct_sizes = sizeof(std::size_t) != 8 ? num_distinct_sizes_32_bit : num_distinct_sizes_64_bit, }; // Originally taken from the SGI implementation; acknowledged in the docs. // Further modified (for 64 bits) from tr1's hashtable. static const std::size_t g_a_sizes[num_distinct_sizes_64_bit] = { /* 0 */ 5ul, /* 1 */ 11ul, /* 2 */ 23ul, /* 3 */ 47ul, /* 4 */ 97ul, /* 5 */ 199ul, /* 6 */ 409ul, /* 7 */ 823ul, /* 8 */ 1741ul, /* 9 */ 3469ul, /* 10 */ 6949ul, /* 11 */ 14033ul, /* 12 */ 28411ul, /* 13 */ 57557ul, /* 14 */ 116731ul, /* 15 */ 236897ul, /* 16 */ 480881ul, /* 17 */ 976369ul, /* 18 */ 1982627ul, /* 19 */ 4026031ul, /* 20 */ 8175383ul, /* 21 */ 16601593ul, /* 22 */ 33712729ul, /* 23 */ 68460391ul, /* 24 */ 139022417ul, /* 25 */ 282312799ul, /* 26 */ 573292817ul, /* 27 */ 1164186217ul, /* 28 */ 2364114217ul, /* 29 */ 4294967291ul, /* 30 */ (std::size_t)8589934583ull, /* 31 */ (std::size_t)17179869143ull, /* 32 */ (std::size_t)34359738337ull, /* 33 */ (std::size_t)68719476731ull, /* 34 */ (std::size_t)137438953447ull, /* 35 */ (std::size_t)274877906899ull, /* 36 */ (std::size_t)549755813881ull, /* 37 */ (std::size_t)1099511627689ull, /* 38 */ (std::size_t)2199023255531ull, /* 39 */ (std::size_t)4398046511093ull, /* 40 */ (std::size_t)8796093022151ull, /* 41 */ (std::size_t)17592186044399ull, /* 42 */ (std::size_t)35184372088777ull, /* 43 */ (std::size_t)70368744177643ull, /* 44 */ (std::size_t)140737488355213ull, /* 45 */ (std::size_t)281474976710597ull, /* 46 */ (std::size_t)562949953421231ull, /* 47 */ (std::size_t)1125899906842597ull, /* 48 */ (std::size_t)2251799813685119ull, /* 49 */ (std::size_t)4503599627370449ull, /* 50 */ (std::size_t)9007199254740881ull, /* 51 */ (std::size_t)18014398509481951ull, /* 52 */ (std::size_t)36028797018963913ull, /* 53 */ (std::size_t)72057594037927931ull, /* 54 */ (std::size_t)144115188075855859ull, /* 55 */ (std::size_t)288230376151711717ull, /* 56 */ (std::size_t)576460752303423433ull, /* 57 */ (std::size_t)1152921504606846883ull, /* 58 */ (std::size_t)2305843009213693951ull, /* 59 */ (std::size_t)4611686018427387847ull, /* 60 */ (std::size_t)9223372036854775783ull, /* 61 */ (std::size_t)18446744073709551557ull, }; } // namespace detail PB_DS_CLASS_T_DEC inline PB_DS_CLASS_C_DEC:: hash_prime_size_policy(size_type n) : m_start_size(n) { m_start_size = get_nearest_larger_size(n); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_start_size, other.m_start_size); } PB_DS_CLASS_T_DEC inline PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_nearest_larger_size(size_type n) const { const std::size_t* const p_upper = std::upper_bound(detail::g_a_sizes, detail::g_a_sizes + detail::num_distinct_sizes, n); if (p_upper == detail::g_a_sizes + detail::num_distinct_sizes) __throw_resize_error(); return *p_upper; } PB_DS_CLASS_T_DEC inline PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_nearest_smaller_size(size_type n) const { const std::size_t* p_lower = std::lower_bound(detail::g_a_sizes, detail::g_a_sizes + detail::num_distinct_sizes, n); if (*p_lower >= n && p_lower != detail::g_a_sizes) --p_lower; if (*p_lower < m_start_size) return m_start_size; return *p_lower; } 8/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp000064400000005632152526447520023666 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_load_check_resize_trigger_size_base.hpp * Contains an base holding size for some resize policies. */ #ifndef PB_DS_HASH_LOAD_CHECK_RESIZE_TRIGGER_SIZE_BASE_HPP #define PB_DS_HASH_LOAD_CHECK_RESIZE_TRIGGER_SIZE_BASE_HPP namespace __gnu_pbds { namespace detail { /// Primary template. template class hash_load_check_resize_trigger_size_base; /// Specializations. template class hash_load_check_resize_trigger_size_base { protected: typedef Size_Type size_type; hash_load_check_resize_trigger_size_base(): m_size(0) { } inline void swap(hash_load_check_resize_trigger_size_base& other) { std::swap(m_size, other.m_size); } inline void set_size(size_type size) { m_size = size; } inline size_type get_size() const { return m_size; } private: size_type m_size; }; template class hash_load_check_resize_trigger_size_base { protected: typedef Size_Type size_type; protected: inline void swap(hash_load_check_resize_trigger_size_base& other) { } inline void set_size(size_type size) { } }; } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/tree_policy/order_statistics_imp.hpp000064400000007213152526447520017344 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tree_policy/order_statistics_imp.hpp * Contains forward declarations for order_statistics_key */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: find_by_order(size_type order) { node_iterator it = node_begin(); node_iterator end_it = node_end(); while (it != end_it) { node_iterator l_it = it.get_l_child(); const size_type o = (l_it == end_it)? 0 : l_it.get_metadata(); if (order == o) return *it; else if (order < o) it = l_it; else { order -= o + 1; it = it.get_r_child(); } } return base_type::end_iterator(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: find_by_order(size_type order) const { return const_cast(this)->find_by_order(order); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: order_of_key(key_const_reference r_key) const { node_const_iterator it = node_begin(); node_const_iterator end_it = node_end(); const cmp_fn& r_cmp_fn = const_cast(this)->get_cmp_fn(); size_type ord = 0; while (it != end_it) { node_const_iterator l_it = it.get_l_child(); if (r_cmp_fn(r_key, this->extract_key(*(*it)))) it = l_it; else if (r_cmp_fn(this->extract_key(*(*it)), r_key)) { ord += (l_it == end_it)? 1 : 1 + l_it.get_metadata(); it = it.get_r_child(); } else { ord += (l_it == end_it)? 0 : l_it.get_metadata(); it = end_it; } } return ord; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: operator()(node_iterator node_it, node_const_iterator end_nd_it) const { node_iterator l_it = node_it.get_l_child(); const size_type l_rank = (l_it == end_nd_it) ? 0 : l_it.get_metadata(); node_iterator r_it = node_it.get_r_child(); const size_type r_rank = (r_it == end_nd_it) ? 0 : r_it.get_metadata(); const_cast(node_it.get_metadata())= 1 + l_rank + r_rank; } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~tree_order_statistics_node_update() { } 8/ext/pb_ds/detail/tree_policy/node_metadata_selector.hpp000064400000006412152526447520017577 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tree_policy/node_metadata_selector.hpp * Contains an implementation class for trees. */ #ifndef PB_DS_TREE_NODE_METADATA_DISPATCH_HPP #define PB_DS_TREE_NODE_METADATA_DISPATCH_HPP #include #include namespace __gnu_pbds { namespace detail { /** * @addtogroup traits Traits * @{ */ /// Tree metadata helper. template struct tree_metadata_helper; /// Specialization, false. template struct tree_metadata_helper { typedef typename Node_Update::metadata_type type; }; /// Specialization, true. template struct tree_metadata_helper { typedef null_type type; }; /// Tree node metadata dispatch. template class Node_Update, typename _Alloc> struct tree_node_metadata_dispatch { private: typedef dumnode_const_iterator __it_type; typedef Node_Update<__it_type, __it_type, Cmp_Fn, _Alloc> __node_u; typedef null_node_update<__it_type, __it_type, Cmp_Fn, _Alloc> __nnode_u; enum { null_update = is_same<__node_u, __nnode_u>::value }; public: typedef typename tree_metadata_helper<__node_u, null_update>::type type; }; //@} } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_TREE_NODE_METADATA_DISPATCH_HPP 8/ext/pb_ds/detail/tree_policy/sample_tree_node_update.hpp000064400000004452152526447520017763 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tree_policy/sample_tree_node_update.hpp * Contains a samle node update functor. */ #ifndef PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP #define PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP namespace __gnu_pbds { /// A sample node updator. template class sample_tree_node_update { typedef std::size_t metadata_type; /// Default constructor. sample_tree_node_update(); /// Updates the rank of a node through a node_iterator node_it; /// end_nd_it is the end node iterator. inline void operator()(node_iterator node_it, node_const_iterator end_nd_it) const; }; } #endif // #ifndef PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP 8/ext/pb_ds/detail/eq_fn/eq_by_less.hpp000064400000004432152526447520014011 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file eq_by_less.hpp * Contains an equivalence function. */ #ifndef PB_DS_EQ_BY_LESS_HPP #define PB_DS_EQ_BY_LESS_HPP #include #include #include #include #include namespace __gnu_pbds { namespace detail { /// Equivalence function. template struct eq_by_less : private Cmp_Fn { bool operator()(const Key& r_lhs, const Key& r_rhs) const { const bool l = Cmp_Fn::operator()(r_lhs, r_rhs); const bool g = Cmp_Fn::operator()(r_rhs, r_lhs); return !(l || g); } }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_EQ_BY_LESS_HPP 8/ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp000064400000007355152526447520013766 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_eq_fn.hpp * Contains 2 eqivalence functions, one employing a hash value, * and one ignoring it. */ #ifndef PB_DS_HASH_EQ_FN_HPP #define PB_DS_HASH_EQ_FN_HPP #include #include namespace __gnu_pbds { namespace detail { /// Primary template. template struct hash_eq_fn; /// Specialization 1 - The client requests that hash values not be stored. template struct hash_eq_fn : public Eq_Fn { typedef Eq_Fn eq_fn_base; typedef typename _Alloc::template rebind::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; hash_eq_fn() { } hash_eq_fn(const Eq_Fn& r_eq_fn) : Eq_Fn(r_eq_fn) { } bool operator()(key_const_reference r_lhs_key, key_const_reference r_rhs_key) const { return eq_fn_base::operator()(r_lhs_key, r_rhs_key); } void swap(const hash_eq_fn& other) { std::swap((Eq_Fn&)(*this), (Eq_Fn&)other); } }; /// Specialization 2 - The client requests that hash values be stored. template struct hash_eq_fn : public Eq_Fn { typedef typename _Alloc::size_type size_type; typedef Eq_Fn eq_fn_base; typedef typename _Alloc::template rebind::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; hash_eq_fn() { } hash_eq_fn(const Eq_Fn& r_eq_fn) : Eq_Fn(r_eq_fn) { } bool operator()(key_const_reference r_lhs_key, size_type lhs_hash, key_const_reference r_rhs_key, size_type rhs_hash) const { _GLIBCXX_DEBUG_ASSERT(!eq_fn_base::operator()(r_lhs_key, r_rhs_key) || lhs_hash == rhs_hash); return (lhs_hash == rhs_hash && eq_fn_base::operator()(r_lhs_key, r_rhs_key)); } void swap(const hash_eq_fn& other) { std::swap((Eq_Fn&)(*this), (Eq_Fn&)(other)); } }; } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/left_child_next_sibling_heap_/const_iterator.hpp000064400000011474152526447520021635 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/const_iterator.hpp * Contains an iterator class returned by the table's const find and insert * methods. */ #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_ITERATOR_HPP #define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_ITERATOR_HPP #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_C_DEC \ left_child_next_sibling_heap_const_iterator_ #define PB_DS_BASIC_HEAP_CIT_BASE \ left_child_next_sibling_heap_node_point_const_iterator_ /// Const point-type iterator. template class left_child_next_sibling_heap_const_iterator_ : public PB_DS_BASIC_HEAP_CIT_BASE { private: typedef PB_DS_BASIC_HEAP_CIT_BASE base_type; typedef typename base_type::node_pointer node_pointer; public: /// Category. typedef std::forward_iterator_tag iterator_category; /// Difference type. typedef typename _Alloc::difference_type difference_type; /// Iterator's value type. typedef typename base_type::value_type value_type; /// Iterator's pointer type. typedef typename base_type::pointer pointer; /// Iterator's const pointer type. typedef typename base_type::const_pointer const_pointer; /// Iterator's reference type. typedef typename base_type::reference reference; /// Iterator's const reference type. typedef typename base_type::const_reference const_reference; inline left_child_next_sibling_heap_const_iterator_(node_pointer p_nd) : base_type(p_nd) { } /// Default constructor. inline left_child_next_sibling_heap_const_iterator_() { } /// Copy constructor. inline left_child_next_sibling_heap_const_iterator_(const PB_DS_CLASS_C_DEC& other) : base_type(other) { } /// Compares content to a different iterator object. bool operator==(const PB_DS_CLASS_C_DEC& other) const { return (base_type::m_p_nd == other.m_p_nd); } /// Compares content (negatively) to a different iterator object. bool operator!=(const PB_DS_CLASS_C_DEC& other) const { return (base_type::m_p_nd != other.m_p_nd); } PB_DS_CLASS_C_DEC& operator++() { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd != 0); inc(); return (*this); } PB_DS_CLASS_C_DEC operator++(int) { PB_DS_CLASS_C_DEC ret_it(base_type::m_p_nd); operator++(); return (ret_it); } private: void inc() { if (base_type::m_p_nd->m_p_next_sibling != 0) { base_type::m_p_nd = base_type::m_p_nd->m_p_next_sibling; while (base_type::m_p_nd->m_p_l_child != 0) base_type::m_p_nd = base_type::m_p_nd->m_p_l_child; return; } while (true) { node_pointer p_next = base_type::m_p_nd; base_type::m_p_nd = base_type::m_p_nd->m_p_prev_or_parent; if (base_type::m_p_nd == 0 || base_type::m_p_nd->m_p_l_child == p_next) return; } } }; #undef PB_DS_CLASS_C_DEC #undef PB_DS_BASIC_HEAP_CIT_BASE } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/left_child_next_sibling_heap_/node.hpp000064400000006214152526447520017517 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/node.hpp * Contains an implementation struct for this type of heap's node. */ #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP #define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP namespace __gnu_pbds { namespace detail { /// Node. template struct left_child_next_sibling_heap_node_ { private: typedef left_child_next_sibling_heap_node_<_Value, _Metadata, _Alloc> this_type; public: typedef _Value value_type; typedef typename _Alloc::size_type size_type; typedef _Metadata metadata_type; typedef typename _Alloc::template rebind::other::pointer node_pointer; value_type m_value; metadata_type m_metadata; node_pointer m_p_l_child; node_pointer m_p_next_sibling; node_pointer m_p_prev_or_parent; }; template struct left_child_next_sibling_heap_node_<_Value, null_type, _Alloc> { private: typedef left_child_next_sibling_heap_node_<_Value, null_type, _Alloc> this_type; public: typedef _Value value_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::template rebind::other::pointer node_pointer; value_type m_value; node_pointer m_p_l_child; node_pointer m_p_next_sibling; node_pointer m_p_prev_or_parent; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP 8/ext/pb_ds/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp000064400000005377152526447520021414 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/trace_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ #ifdef PB_DS_LC_NS_HEAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << std::endl; trace_node(m_p_root, 0); std::cerr << std::endl; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node(node_const_pointer p_nd, size_type level) { while (p_nd != 0) { for (size_type i = 0; i < level; ++i) std::cerr << ' '; std::cerr << p_nd << " prev = " << p_nd->m_p_prev_or_parent << " next " << p_nd->m_p_next_sibling << " left = " << p_nd->m_p_l_child << " "; trace_node_metadata(p_nd, type_to_type()); std::cerr << p_nd->m_value << std::endl; trace_node(p_nd->m_p_l_child, level + 1); p_nd = p_nd->m_p_next_sibling; } } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: trace_node_metadata(node_const_pointer p_nd, type_to_type) { std::cerr << "(" << p_nd->m_metadata << ") "; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node_metadata(node_const_pointer, type_to_type) { } #endif // #ifdef PB_DS_LC_NS_HEAP_TRACE_ 8/ext/pb_ds/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp000064400000003607152526447520023130 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/policy_access_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() { return *this; } PB_DS_CLASS_T_DEC const Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() const { return *this; } 8/ext/pb_ds/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp000064400000007727152526447520025345 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_allocator PB_DS_CLASS_C_DEC::s_node_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::no_throw_copies_t PB_DS_CLASS_C_DEC::s_no_throw_copies_ind; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: left_child_next_sibling_heap() : m_p_root(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: left_child_next_sibling_heap(const Cmp_Fn& r_cmp_fn) : Cmp_Fn(r_cmp_fn), m_p_root(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: left_child_next_sibling_heap(const PB_DS_CLASS_C_DEC& other) : Cmp_Fn(other), m_p_root(0), m_size(0) { m_size = other.m_size; PB_DS_ASSERT_VALID(other) m_p_root = recursive_copy_node(other.m_p_root); m_size = other.m_size; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) value_swap(other); std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_p_root, other.m_p_root); std::swap(m_size, other.m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~left_child_next_sibling_heap() { clear(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: recursive_copy_node(node_const_pointer p_nd) { if (p_nd == 0) return (0); node_pointer p_ret = s_node_allocator.allocate(1); __try { new (p_ret) node(*p_nd); } __catch(...) { s_node_allocator.deallocate(p_ret, 1); __throw_exception_again; } p_ret->m_p_l_child = p_ret->m_p_next_sibling = p_ret->m_p_prev_or_parent = 0; __try { p_ret->m_p_l_child = recursive_copy_node(p_nd->m_p_l_child); p_ret->m_p_next_sibling = recursive_copy_node(p_nd->m_p_next_sibling); } __catch(...) { clear_imp(p_ret); __throw_exception_again; } if (p_ret->m_p_l_child != 0) p_ret->m_p_l_child->m_p_prev_or_parent = p_ret; if (p_ret->m_p_next_sibling != 0) p_ret->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_next_sibling->m_p_prev_or_parent == p_nd ? p_ret : 0; return p_ret; } 8/ext/pb_ds/detail/left_child_next_sibling_heap_/point_const_iterator.hpp000064400000010620152526447520023036 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/point_const_iterator.hpp * Contains an iterator class returned by the table's const find and insert * methods. */ #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_FIND_ITERATOR_HPP #define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_FIND_ITERATOR_HPP #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ left_child_next_sibling_heap_node_point_const_iterator_ /// Const point-type iterator. template class left_child_next_sibling_heap_node_point_const_iterator_ { protected: typedef typename _Alloc::template rebind::other::pointer node_pointer; public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef typename Node::value_type value_type; /// Iterator's pointer type. typedef typename _Alloc::template rebind< value_type>::other::pointer pointer; /// Iterator's const pointer type. typedef typename _Alloc::template rebind< value_type>::other::const_pointer const_pointer; /// Iterator's reference type. typedef typename _Alloc::template rebind< value_type>::other::reference reference; /// Iterator's const reference type. typedef typename _Alloc::template rebind< value_type>::other::const_reference const_reference; inline left_child_next_sibling_heap_node_point_const_iterator_(node_pointer p_nd) : m_p_nd(p_nd) { } /// Default constructor. inline left_child_next_sibling_heap_node_point_const_iterator_() : m_p_nd(0) { } /// Copy constructor. inline left_child_next_sibling_heap_node_point_const_iterator_(const PB_DS_CLASS_C_DEC& other) : m_p_nd(other.m_p_nd) { } /// Access. const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); return &m_p_nd->m_value; } /// Access. const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); return m_p_nd->m_value; } /// Compares content to a different iterator object. bool operator==(const PB_DS_CLASS_C_DEC& other) const { return m_p_nd == other.m_p_nd; } /// Compares content (negatively) to a different iterator object. bool operator!=(const PB_DS_CLASS_C_DEC& other) const { return m_p_nd != other.m_p_nd; } node_pointer m_p_nd; }; #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp000064400000004072152526447520021240 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/info_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (m_size == 0); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return (m_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return (s_node_allocator.max_size()); } 8/ext/pb_ds/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp000064400000004773152526447520022331 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/iterators_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { node_pointer p_nd = m_p_root; if (p_nd == 0) return (iterator(0)); while (p_nd->m_p_l_child != 0) p_nd = p_nd->m_p_l_child; return (iterator(p_nd)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { node_pointer p_nd = m_p_root; if (p_nd == 0) return (const_iterator(0)); while (p_nd->m_p_l_child != 0) p_nd = p_nd->m_p_l_child; return (const_iterator(p_nd)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return (iterator(0)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return (const_iterator(0)); } 8/ext/pb_ds/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp000064400000007753152526447520021404 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/debug_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_p_root == 0 || m_p_root->m_p_prev_or_parent == 0); if (m_p_root != 0) assert_node_consistent(m_p_root, Single_Link_Roots, __file, __line); assert_size(__file, __line); assert_iterators(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent(node_const_pointer p_nd, bool single_link, const char* __file, int __line) const { if (p_nd == 0) return; assert_node_consistent(p_nd->m_p_l_child, false, __file, __line); assert_node_consistent(p_nd->m_p_next_sibling, single_link, __file, __line); if (single_link) PB_DS_DEBUG_VERIFY(p_nd->m_p_prev_or_parent == 0); else if (p_nd->m_p_next_sibling != 0) PB_DS_DEBUG_VERIFY(p_nd->m_p_next_sibling->m_p_prev_or_parent == p_nd); if (p_nd->m_p_l_child == 0) return; node_const_pointer p_child = p_nd->m_p_l_child; while (p_child != 0) { node_const_pointer p_next_child = p_child->m_p_next_sibling; PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(p_nd->m_value, p_child->m_value)); p_child = p_next_child; } PB_DS_DEBUG_VERIFY(p_nd->m_p_l_child->m_p_prev_or_parent == p_nd); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_iterators(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(std::distance(begin(), end()) == size()); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_size(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(size_from_node(m_p_root) == m_size); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size_under_node(node_const_pointer p_nd) { return 1 + size_from_node(p_nd->m_p_l_child); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size_from_node(node_const_pointer p_nd) { size_type ret = 0; while (p_nd != 0) { ret += 1 + size_from_node(p_nd->m_p_l_child); p_nd = p_nd->m_p_next_sibling; } return ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: degree(node_const_pointer p_nd) { size_type ret = 0; node_const_pointer p_child = p_nd->m_p_l_child; while (p_child != 0) { ++ret; p_child = p_child->m_p_next_sibling; } return ret; } #endif 8/ext/pb_ds/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp000064400000012121152526447520021603 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/insert_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_insert(const_reference r_val) { return get_new_node_for_insert(r_val, s_no_throw_copies_ind); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_insert(const_reference r_val, false_type) { node_pointer p_new_nd = s_node_allocator.allocate(1); cond_dealtor_t cond(p_new_nd); new (const_cast( static_cast(&p_new_nd->m_value))) typename node::value_type(r_val); cond.set_no_action(); ++m_size; return (p_new_nd); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_insert(const_reference r_val, true_type) { node_pointer p_new_nd = s_node_allocator.allocate(1); new (const_cast( static_cast(&p_new_nd->m_value))) typename node::value_type(r_val); ++m_size; return (p_new_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_child_of(node_pointer p_nd, node_pointer p_new_parent) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_new_parent != 0); p_nd->m_p_next_sibling = p_new_parent->m_p_l_child; if (p_new_parent->m_p_l_child != 0) p_new_parent->m_p_l_child->m_p_prev_or_parent = p_nd; p_nd->m_p_prev_or_parent = p_new_parent; p_new_parent->m_p_l_child = p_nd; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: parent(node_pointer p_nd) { while (true) { node_pointer p_pot = p_nd->m_p_prev_or_parent; if (p_pot == 0 || p_pot->m_p_l_child == p_nd) return p_pot; p_nd = p_pot; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap_with_parent(node_pointer p_nd, node_pointer p_parent) { if (p_parent == m_p_root) m_p_root = p_nd; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_parent != 0); _GLIBCXX_DEBUG_ASSERT(parent(p_nd) == p_parent); const bool nd_direct_child = p_parent->m_p_l_child == p_nd; const bool parent_root = p_parent->m_p_prev_or_parent == 0; const bool parent_direct_child = !parent_root&& p_parent->m_p_prev_or_parent->m_p_l_child == p_parent; std::swap(p_parent->m_p_prev_or_parent, p_nd->m_p_prev_or_parent); std::swap(p_parent->m_p_next_sibling, p_nd->m_p_next_sibling); std::swap(p_parent->m_p_l_child, p_nd->m_p_l_child); std::swap(p_parent->m_metadata, p_nd->m_metadata); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child != 0); _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_prev_or_parent != 0); if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; if (p_parent->m_p_next_sibling != 0) p_parent->m_p_next_sibling->m_p_prev_or_parent = p_parent; if (p_parent->m_p_l_child != 0) p_parent->m_p_l_child->m_p_prev_or_parent = p_parent; if (parent_direct_child) p_nd->m_p_prev_or_parent->m_p_l_child = p_nd; else if (!parent_root) p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd; if (!nd_direct_child) { p_nd->m_p_l_child->m_p_prev_or_parent = p_nd; p_parent->m_p_prev_or_parent->m_p_next_sibling = p_parent; } else { _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child == p_nd); _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_prev_or_parent == p_parent); p_nd->m_p_l_child = p_parent; p_parent->m_p_prev_or_parent = p_nd; } _GLIBCXX_DEBUG_ASSERT(parent(p_parent) == p_nd); } 8/ext/pb_ds/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp000064400000007567152526447520021420 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/erase_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { clear_imp(m_p_root); _GLIBCXX_DEBUG_ASSERT(m_size == 0); m_p_root = 0; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_node(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; p_nd->~node(); s_node_allocator.deallocate(p_nd, 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { while (p_nd != 0) { clear_imp(p_nd->m_p_l_child); node_pointer p_next = p_nd->m_p_next_sibling; actual_erase_node(p_nd); p_nd = p_next; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: to_linked_list() { PB_DS_ASSERT_VALID((*this)) node_pointer p_cur = m_p_root; while (p_cur != 0) if (p_cur->m_p_l_child != 0) { node_pointer p_child_next = p_cur->m_p_l_child->m_p_next_sibling; p_cur->m_p_l_child->m_p_next_sibling = p_cur->m_p_next_sibling; p_cur->m_p_next_sibling = p_cur->m_p_l_child; p_cur->m_p_l_child = p_child_next; } else p_cur = p_cur->m_p_next_sibling; #ifdef _GLIBCXX_DEBUG node_const_pointer p_counter = m_p_root; size_type count = 0; while (p_counter != 0) { ++count; _GLIBCXX_DEBUG_ASSERT(p_counter->m_p_l_child == 0); p_counter = p_counter->m_p_next_sibling; } _GLIBCXX_DEBUG_ASSERT(count == m_size); #endif } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: prune(Pred pred) { node_pointer p_cur = m_p_root; m_p_root = 0; node_pointer p_out = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; if (pred(p_cur->m_value)) { p_cur->m_p_next_sibling = p_out; if (p_out != 0) p_out->m_p_prev_or_parent = p_cur; p_out = p_cur; } else { p_cur->m_p_next_sibling = m_p_root; if (m_p_root != 0) m_p_root->m_p_prev_or_parent = p_cur; m_p_root = p_cur; } p_cur = p_next; } return p_out; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: bubble_to_top(node_pointer p_nd) { node_pointer p_parent = parent(p_nd); while (p_parent != 0) { swap_with_parent(p_nd, p_parent); p_parent = parent(p_nd); } } 8/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp000064400000017757152526447520024606 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp * Contains an implementation class for a basic heap. */ #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_HPP #define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_HPP /* * Based on CLRS. */ #include #include #include #include #include #include #ifdef PB_DS_LC_NS_HEAP_TRACE_ #include #endif #include namespace __gnu_pbds { namespace detail { #ifdef _GLIBCXX_DEBUG #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ left_child_next_sibling_heap #else #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ left_child_next_sibling_heap #endif /// Base class for a basic heap. template #else > #endif class left_child_next_sibling_heap : public Cmp_Fn { protected: typedef typename _Alloc::template rebind< left_child_next_sibling_heap_node_ >::other node_allocator; typedef typename node_allocator::value_type node; typedef typename node_allocator::pointer node_pointer; typedef typename node_allocator::const_pointer node_const_pointer; typedef Node_Metadata node_metadata; typedef std::pair< node_pointer, node_pointer> node_pointer_pair; private: typedef cond_dealtor< node, _Alloc> cond_dealtor_t; enum { simple_value = is_simple::value }; typedef integral_constant no_throw_copies_t; typedef typename _Alloc::template rebind __rebind_v; public: typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Value_Type value_type; typedef typename __rebind_v::other::pointer pointer; typedef typename __rebind_v::other::const_pointer const_pointer; typedef typename __rebind_v::other::reference reference; typedef typename __rebind_v::other::const_reference const_reference; typedef left_child_next_sibling_heap_node_point_const_iterator_ point_const_iterator; typedef point_const_iterator point_iterator; typedef left_child_next_sibling_heap_const_iterator_ const_iterator; typedef const_iterator iterator; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; left_child_next_sibling_heap(); left_child_next_sibling_heap(const Cmp_Fn&); left_child_next_sibling_heap(const left_child_next_sibling_heap&); void swap(PB_DS_CLASS_C_DEC&); ~left_child_next_sibling_heap(); inline bool empty() const; inline size_type size() const; inline size_type max_size() const; Cmp_Fn& get_cmp_fn(); const Cmp_Fn& get_cmp_fn() const; inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; void clear(); #ifdef PB_DS_LC_NS_HEAP_TRACE_ void trace() const; #endif protected: inline node_pointer get_new_node_for_insert(const_reference); inline static void make_child_of(node_pointer, node_pointer); void value_swap(left_child_next_sibling_heap&); inline static node_pointer parent(node_pointer); inline void swap_with_parent(node_pointer, node_pointer); void bubble_to_top(node_pointer); inline void actual_erase_node(node_pointer); void clear_imp(node_pointer); void to_linked_list(); template node_pointer prune(Pred); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void assert_node_consistent(node_const_pointer, bool, const char*, int) const; static size_type size_under_node(node_const_pointer); static size_type degree(node_const_pointer); #endif #ifdef PB_DS_LC_NS_HEAP_TRACE_ static void trace_node(node_const_pointer, size_type); #endif private: #ifdef _GLIBCXX_DEBUG void assert_iterators(const char*, int) const; void assert_size(const char*, int) const; static size_type size_from_node(node_const_pointer); #endif node_pointer recursive_copy_node(node_const_pointer); inline node_pointer get_new_node_for_insert(const_reference, false_type); inline node_pointer get_new_node_for_insert(const_reference, true_type); #ifdef PB_DS_LC_NS_HEAP_TRACE_ template static void trace_node_metadata(node_const_pointer, type_to_type); static void trace_node_metadata(node_const_pointer, type_to_type); #endif static node_allocator s_node_allocator; static no_throw_copies_t s_no_throw_copies_ind; protected: node_pointer m_p_root; size_type m_size; }; #include #include #include #include #include #include #include #include #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/list_update_map_/entry_metadata_base.hpp000064400000004105152526447520020075 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/entry_metadata_base.hpp * Contains an implementation for a list update map. */ #ifndef PB_DS_LU_MAP_ENTRY_METADATA_BASE_HPP #define PB_DS_LU_MAP_ENTRY_METADATA_BASE_HPP namespace __gnu_pbds { namespace detail { template struct lu_map_entry_metadata_base { Metadata m_update_metadata; }; template<> struct lu_map_entry_metadata_base { }; } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/list_update_map_/trace_fn_imps.hpp000064400000003754152526447520016724 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/trace_fn_imps.hpp * Contains implementations of lu_map_. */ #ifdef PB_DS_LU_MAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << m_p_l << std::endl << std::endl; const_entry_pointer p_l = m_p_l; while (p_l != 0) { std::cerr << PB_DS_V2F(p_l->m_value) << std::endl; p_l = p_l->m_p_next; } std::cerr << std::endl; } #endif 8/ext/pb_ds/detail/list_update_map_/constructor_destructor_fn_imps.hpp000064400000007000152526447520022455 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/constructor_destructor_fn_imps.hpp */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_allocator PB_DS_CLASS_C_DEC::s_entry_allocator; PB_DS_CLASS_T_DEC Eq_Fn PB_DS_CLASS_C_DEC::s_eq_fn; PB_DS_CLASS_T_DEC null_type PB_DS_CLASS_C_DEC::s_null_type; PB_DS_CLASS_T_DEC Update_Policy PB_DS_CLASS_C_DEC::s_update_policy; PB_DS_CLASS_T_DEC type_to_type< typename PB_DS_CLASS_C_DEC::update_metadata> PB_DS_CLASS_C_DEC::s_metadata_type_indicator; PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_LU_NAME() : m_p_l(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template PB_DS_CLASS_C_DEC:: PB_DS_LU_NAME(It first_it, It last_it) : m_p_l(0) { copy_from_range(first_it, last_it); PB_DS_ASSERT_VALID((*this)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_LU_NAME(const PB_DS_CLASS_C_DEC& other) : m_p_l(0) { __try { for (const_iterator it = other.begin(); it != other.end(); ++it) { entry_pointer p_l = allocate_new_entry(*it, traits_base::m_no_throw_copies_indicator); p_l->m_p_next = m_p_l; m_p_l = p_l; } } __catch(...) { deallocate_all(); __throw_exception_again; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);) std::swap(m_p_l, other.m_p_l); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: deallocate_all() { entry_pointer p_l = m_p_l; while (p_l != 0) { entry_pointer p_next_l = p_l->m_p_next; actual_erase_entry(p_l); p_l = p_next_l; } m_p_l = 0; } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_LU_NAME() { deallocate_all(); } 8/ext/pb_ds/detail/list_update_map_/lu_map_.hpp000064400000024231152526447520015520 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/lu_map_.hpp * Contains a list update map. */ #include #include #include #include #include #include #include #ifdef _GLIBCXX_DEBUG #include #endif #ifdef PB_DS_LU_MAP_TRACE_ #include #endif #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_LU_NAME lu_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_LU_NAME lu_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_LU_NAME #define PB_DS_LU_TRAITS_BASE \ types_traits #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base::other::const_reference> #endif /// list-based (with updates) associative container. /// Skip to the lu, my darling. template class PB_DS_LU_NAME : #ifdef _GLIBCXX_DEBUG protected PB_DS_DEBUG_MAP_BASE_C_DEC, #endif public PB_DS_LU_TRAITS_BASE { private: typedef PB_DS_LU_TRAITS_BASE traits_base; struct entry : public lu_map_entry_metadata_base { typename traits_base::value_type m_value; typename _Alloc::template rebind::other::pointer m_p_next; }; typedef typename _Alloc::template rebind::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; typedef typename entry_allocator::const_pointer const_entry_pointer; typedef typename entry_allocator::reference entry_reference; typedef typename entry_allocator::const_reference const_entry_reference; typedef typename _Alloc::template rebind::other entry_pointer_allocator; typedef typename entry_pointer_allocator::pointer entry_pointer_array; typedef typename traits_base::value_type value_type_; typedef typename traits_base::pointer pointer_; typedef typename traits_base::const_pointer const_pointer_; typedef typename traits_base::reference reference_; typedef typename traits_base::const_reference const_reference_; #define PB_DS_GEN_POS entry_pointer #include #include #include #include #undef PB_DS_GEN_POS #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif typedef cond_dealtor cond_dealtor_t; public: typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Eq_Fn eq_fn; typedef Update_Policy update_policy; typedef typename Update_Policy::metadata_type update_metadata; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef point_iterator_ point_iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef point_const_iterator_ point_iterator; #endif typedef point_const_iterator_ point_const_iterator; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef iterator_ iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef const_iterator_ iterator; #endif typedef const_iterator_ const_iterator; public: PB_DS_LU_NAME(); PB_DS_LU_NAME(const PB_DS_CLASS_C_DEC&); virtual ~PB_DS_LU_NAME(); template PB_DS_LU_NAME(It, It); void swap(PB_DS_CLASS_C_DEC&); inline size_type size() const; inline size_type max_size() const; inline bool empty() const; inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return insert(std::make_pair(r_key, mapped_type())).first->second; #else insert(r_key); return traits_base::s_null_type; #endif } inline std::pair insert(const_reference); inline point_iterator find(key_const_reference r_key) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) entry_pointer p_e = find_imp(r_key); return point_iterator(p_e == 0 ? 0: &p_e->m_value); } inline point_const_iterator find(key_const_reference r_key) const { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) entry_pointer p_e = find_imp(r_key); return point_const_iterator(p_e == 0 ? 0: &p_e->m_value); } inline bool erase(key_const_reference); template inline size_type erase_if(Pred); void clear(); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char* file, int line) const; #endif #ifdef PB_DS_LU_MAP_TRACE_ void trace() const; #endif protected: template void copy_from_range(It, It); private: #ifdef PB_DS_DATA_TRUE_INDICATOR friend class iterator_; #endif friend class const_iterator_; inline entry_pointer allocate_new_entry(const_reference, false_type); inline entry_pointer allocate_new_entry(const_reference, true_type); template inline static void init_entry_metadata(entry_pointer, type_to_type); inline static void init_entry_metadata(entry_pointer, type_to_type); void deallocate_all(); void erase_next(entry_pointer); void actual_erase_entry(entry_pointer); void inc_it_state(const_pointer& r_p_value, entry_pointer& r_pos) const { r_pos = r_pos->m_p_next; r_p_value = (r_pos == 0) ? 0 : &r_pos->m_value; } template inline static bool apply_update(entry_pointer, type_to_type); inline static bool apply_update(entry_pointer, type_to_type); inline entry_pointer find_imp(key_const_reference) const; static entry_allocator s_entry_allocator; static Eq_Fn s_eq_fn; static Update_Policy s_update_policy; static type_to_type s_metadata_type_indicator; static null_type s_null_type; mutable entry_pointer m_p_l; }; #include #include #include #include #include #include #include #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_LU_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #undef PB_DS_LU_NAME } // namespace detail } // namespace __gnu_pbds 8/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp000064400000004032152526447520016547 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/info_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return std::distance(begin(), end()); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_entry_allocator.max_size(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (m_p_l == 0); } 8/ext/pb_ds/detail/list_update_map_/find_fn_imps.hpp000064400000005455152526447520016546 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/find_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: find_imp(key_const_reference r_key) const { if (m_p_l == 0) return 0; if (s_eq_fn(r_key, PB_DS_V2F(m_p_l->m_value))) { apply_update(m_p_l, s_metadata_type_indicator); PB_DS_CHECK_KEY_EXISTS(r_key) return m_p_l; } entry_pointer p_l = m_p_l; while (p_l->m_p_next != 0) { entry_pointer p_next = p_l->m_p_next; if (s_eq_fn(r_key, PB_DS_V2F(p_next->m_value))) { if (apply_update(p_next, s_metadata_type_indicator)) { p_l->m_p_next = p_next->m_p_next; p_next->m_p_next = m_p_l; m_p_l = p_next; return m_p_l; } return p_next; } else p_l = p_next; } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return 0; } PB_DS_CLASS_T_DEC template inline bool PB_DS_CLASS_C_DEC:: apply_update(entry_pointer p_l, type_to_type) { return s_update_policy(p_l->m_update_metadata); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: apply_update(entry_pointer, type_to_type) { return s_update_policy(s_null_type); } 8/ext/pb_ds/detail/list_update_map_/iterators_fn_imps.hpp000064400000004722152526447520017636 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/iterators_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { if (m_p_l == 0) { _GLIBCXX_DEBUG_ASSERT(empty()); return end(); } return iterator(&m_p_l->m_value, m_p_l, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { if (m_p_l == 0) { _GLIBCXX_DEBUG_ASSERT(empty()); return end(); } return iterator(&m_p_l->m_value, m_p_l, const_cast(this)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return iterator(0, 0, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return const_iterator(0, 0, const_cast(this)); } 8/ext/pb_ds/detail/list_update_map_/debug_fn_imps.hpp000064400000004057152526447520016711 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/debug_fn_imps.hpp * Contains implementations of cc_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { size_type calc_size = 0; for (const_iterator it = begin(); it != end(); ++it) { debug_base::check_key_exists(PB_DS_V2F(*it), __file, __line); ++calc_size; } debug_base::check_size(calc_size, __file, __line); } #endif 8/ext/pb_ds/detail/list_update_map_/insert_fn_imps.hpp000064400000006666152526447520017137 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/insert_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline std::pair< typename PB_DS_CLASS_C_DEC::point_iterator, bool> PB_DS_CLASS_C_DEC:: insert(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) entry_pointer p_l = find_imp(PB_DS_V2F(r_val)); if (p_l != 0) { PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(r_val)) return std::make_pair(point_iterator(&p_l->m_value), false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_val)) p_l = allocate_new_entry(r_val, traits_base::m_no_throw_copies_indicator); p_l->m_p_next = m_p_l; m_p_l = p_l; PB_DS_ASSERT_VALID((*this)) return std::make_pair(point_iterator(&p_l->m_value), true); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: allocate_new_entry(const_reference r_val, false_type) { entry_pointer p_l = s_entry_allocator.allocate(1); cond_dealtor_t cond(p_l); new (const_cast(static_cast(&p_l->m_value))) value_type(r_val); cond.set_no_action(); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) init_entry_metadata(p_l, s_metadata_type_indicator); return p_l; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: allocate_new_entry(const_reference r_val, true_type) { entry_pointer p_l = s_entry_allocator.allocate(1); new (&p_l->m_value) value_type(r_val); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) init_entry_metadata(p_l, s_metadata_type_indicator); return p_l; } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: init_entry_metadata(entry_pointer p_l, type_to_type) { new (&p_l->m_update_metadata) Metadata(s_update_policy()); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: init_entry_metadata(entry_pointer, type_to_type) { } 8/ext/pb_ds/detail/list_update_map_/erase_fn_imps.hpp000064400000006632152526447520016723 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/erase_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) if (m_p_l == 0) return false; if (s_eq_fn(r_key, PB_DS_V2F(m_p_l->m_value))) { entry_pointer p_next = m_p_l->m_p_next; actual_erase_entry(m_p_l); m_p_l = p_next; return true; } entry_pointer p_l = m_p_l; while (p_l->m_p_next != 0) if (s_eq_fn(r_key, PB_DS_V2F(p_l->m_p_next->m_value))) { erase_next(p_l); return true; } else p_l = p_l->m_p_next; return false; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { deallocate_all(); } PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) size_type num_ersd = 0; while (m_p_l != 0 && pred(m_p_l->m_value)) { entry_pointer p_next = m_p_l->m_p_next; ++num_ersd; actual_erase_entry(m_p_l); m_p_l = p_next; } if (m_p_l == 0) return num_ersd; entry_pointer p_l = m_p_l; while (p_l->m_p_next != 0) { if (pred(p_l->m_p_next->m_value)) { ++num_ersd; erase_next(p_l); } else p_l = p_l->m_p_next; } PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_next(entry_pointer p_l) { _GLIBCXX_DEBUG_ASSERT(p_l != 0); _GLIBCXX_DEBUG_ASSERT(p_l->m_p_next != 0); entry_pointer p_next_l = p_l->m_p_next->m_p_next; actual_erase_entry(p_l->m_p_next); p_l->m_p_next = p_next_l; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: actual_erase_entry(entry_pointer p_l) { _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_l->m_value));) p_l->~entry(); s_entry_allocator.deallocate(p_l, 1); } 8/ext/pb_ds/detail/unordered_iterator/const_iterator.hpp000064400000006421152526447520017533 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file unordered_iterator/const_iterator.hpp * Contains an iterator class used for const ranging over the elements of the * table. */ /// Const range-type iterator. class const_iterator_ : public point_const_iterator_ { public: /// Category. typedef std::forward_iterator_tag iterator_category; /// Difference type. typedef typename _Alloc::difference_type difference_type; /// Iterator's value type. typedef value_type_ value_type; /// Iterator's pointer type. typedef pointer_ pointer; /// Iterator's const pointer type. typedef const_pointer_ const_pointer; /// Iterator's reference type. typedef reference_ reference; /// Iterator's const reference type. typedef const_reference_ const_reference; /// Default constructor. const_iterator_() : m_p_tbl(0) { } /// Increments. const_iterator_& operator++() { m_p_tbl->inc_it_state(base_type::m_p_value, m_pos); return *this; } /// Increments. const_iterator_ operator++(int) { const_iterator_ ret =* this; m_p_tbl->inc_it_state(base_type::m_p_value, m_pos); return ret; } protected: typedef point_const_iterator_ base_type; /** * Constructor used by the table to initiate the generalized * pointer and position (e.g., this is called from within a find() * of a table. * */ const_iterator_(const_pointer_ p_value, PB_DS_GEN_POS pos, const PB_DS_CLASS_C_DEC* p_tbl) : point_const_iterator_(p_value), m_p_tbl(p_tbl), m_pos(pos) { } /** * Pointer to the table object which created the iterator (used for * incrementing its position. * */ const PB_DS_CLASS_C_DEC* m_p_tbl; PB_DS_GEN_POS m_pos; friend class PB_DS_CLASS_C_DEC; }; 8/ext/pb_ds/detail/unordered_iterator/point_iterator.hpp000064400000006766152526447520017552 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file point_iterator.hpp * Contains an iterator class returned by the tables' find and insert * methods. */ /// Find type iterator. class point_iterator_ { public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef value_type_ value_type; /// Iterator's pointer type. typedef pointer_ pointer; /// Iterator's const pointer type. typedef const_pointer_ const_pointer; /// Iterator's reference type. typedef reference_ reference; /// Iterator's const reference type. typedef const_reference_ const_reference; /// Default constructor. inline point_iterator_() : m_p_value(0) { } /// Copy constructor. inline point_iterator_(const point_iterator_& other) : m_p_value(other.m_p_value) { } /// Access. pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_value != 0); return (m_p_value); } /// Access. reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_value != 0); return (*m_p_value); } /// Compares content to a different iterator object. bool operator==(const point_iterator_& other) const { return m_p_value == other.m_p_value; } /// Compares content to a different iterator object. bool operator==(const point_const_iterator_& other) const { return m_p_value == other.m_p_value; } /// Compares content to a different iterator object. bool operator!=(const point_iterator_& other) const { return m_p_value != other.m_p_value; } /// Compares content (negatively) to a different iterator object. bool operator!=(const point_const_iterator_& other) const { return m_p_value != other.m_p_value; } inline point_iterator_(pointer p_value) : m_p_value(p_value) { } protected: friend class point_const_iterator_; friend class PB_DS_CLASS_C_DEC; protected: pointer m_p_value; }; 8/ext/pb_ds/detail/unordered_iterator/iterator.hpp000064400000007325152526447520016331 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file iterator.hpp * Contains an iterator_ class used for ranging over the elements of the * table. */ /// Range-type iterator. class iterator_ : public const_iterator_ { public: /// Category. typedef std::forward_iterator_tag iterator_category; /// Difference type. typedef typename _Alloc::difference_type difference_type; /// Iterator's value type. typedef value_type_ value_type; /// Iterator's pointer type. typedef pointer_ pointer; /// Iterator's const pointer type. typedef const_pointer_ const_pointer; /// Iterator's reference type. typedef reference_ reference; /// Iterator's const reference type. typedef const_reference_ const_reference; /// Default constructor. inline iterator_() : const_iterator_(0, PB_DS_GEN_POS(), 0) { } /// Conversion to a point-type iterator. inline operator point_iterator_() { return point_iterator_(const_cast(const_iterator_::m_p_value)); } /// Conversion to a point-type iterator. inline operator const point_iterator_() const { return point_iterator_(const_cast(const_iterator_::m_p_value)); } /// Access. pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_value != 0); return (const_cast(base_type::m_p_value)); } /// Access. reference operator*() const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_value != 0); return (const_cast(*base_type::m_p_value)); } /// Increments. iterator_& operator++() { base_type::m_p_tbl->inc_it_state(base_type::m_p_value, base_type::m_pos); return *this; } /// Increments. iterator_ operator++(int) { iterator_ ret =* this; base_type::m_p_tbl->inc_it_state(base_type::m_p_value, base_type::m_pos); return ret; } protected: typedef const_iterator_ base_type; /** * Constructor used by the table to initiate the generalized * pointer and position (e.g., this is called from within a find() * of a table. * */ inline iterator_(pointer p_value, PB_DS_GEN_POS pos, PB_DS_CLASS_C_DEC* p_tbl) : const_iterator_(p_value, pos, p_tbl) { } friend class PB_DS_CLASS_C_DEC; }; 8/ext/pb_ds/detail/unordered_iterator/point_const_iterator.hpp000064400000007336152526447520020752 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file unordered_iterator/point_const_iterator.hpp * Contains an iterator class returned by the tables' const find and insert * methods. */ class point_iterator_; /// Const point-type iterator. class point_const_iterator_ { public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef value_type_ value_type; /// Iterator's pointer type. typedef pointer_ pointer; /// Iterator's const pointer type. typedef const_pointer_ const_pointer; /// Iterator's reference type. typedef reference_ reference; /// Iterator's const reference type. typedef const_reference_ const_reference; inline point_const_iterator_(const_pointer p_value) : m_p_value(p_value) { } /// Default constructor. inline point_const_iterator_() : m_p_value(0) { } /// Copy constructor. inline point_const_iterator_(const point_const_iterator_& other) : m_p_value(other.m_p_value) { } /// Copy constructor. inline point_const_iterator_(const point_iterator_& other) : m_p_value(other.m_p_value) { } /// Access. const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_value != 0); return m_p_value; } /// Access. const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_value != 0); return *m_p_value; } /// Compares content to a different iterator object. bool operator==(const point_iterator_& other) const { return m_p_value == other.m_p_value; } /// Compares content to a different iterator object. bool operator==(const point_const_iterator_& other) const { return m_p_value == other.m_p_value; } /// Compares content (negatively) to a different iterator object. bool operator!=(const point_iterator_& other) const { return m_p_value != other.m_p_value; } /// Compares content (negatively) to a different iterator object. bool operator!=(const point_const_iterator_& other) const { return m_p_value != other.m_p_value; } protected: const_pointer m_p_value; friend class point_iterator_; friend class PB_DS_CLASS_C_DEC; }; 8/ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp000064400000003772152526447520015545 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/update_fn_imps.hpp * Contains an implementation class for pat_trie_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer, null_node_update_pointer) { } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer p_nd, Node_Update_*) { Node_Update_::operator()(node_iterator(p_nd, this), node_const_iterator(0, this)); } 8/ext/pb_ds/detail/pat_trie_/rotate_fn_imps.hpp000064400000010352152526447520015551 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/rotate_fn_imps.hpp * Contains imps for rotating nodes. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_left(node_pointer p_x) { node_pointer p_y = p_x->m_p_right; p_x->m_p_right = p_y->m_p_left; if (p_y->m_p_left != 0) p_y->m_p_left->m_p_parent = p_x; p_y->m_p_parent = p_x->m_p_parent; if (p_x == m_p_head->m_p_parent) m_p_head->m_p_parent = p_y; else if (p_x == p_x->m_p_parent->m_p_left) p_x->m_p_parent->m_p_left = p_y; else p_x->m_p_parent->m_p_right = p_y; p_y->m_p_left = p_x; p_x->m_p_parent = p_y; _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) apply_update(p_x, (Node_Update*)this); apply_update(p_x->m_p_parent, (Node_Update*)this); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_right(node_pointer p_x) { node_pointer p_y = p_x->m_p_left; p_x->m_p_left = p_y->m_p_right; if (p_y->m_p_right != 0) p_y->m_p_right->m_p_parent = p_x; p_y->m_p_parent = p_x->m_p_parent; if (p_x == m_p_head->m_p_parent) m_p_head->m_p_parent = p_y; else if (p_x == p_x->m_p_parent->m_p_right) p_x->m_p_parent->m_p_right = p_y; else p_x->m_p_parent->m_p_left = p_y; p_y->m_p_right = p_x; p_x->m_p_parent = p_y; _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) apply_update(p_x, (Node_Update*)this); apply_update(p_x->m_p_parent, (Node_Update*)this); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_parent(node_pointer p_nd) { node_pointer p_parent = p_nd->m_p_parent; if (p_nd == p_parent->m_p_left) rotate_right(p_parent); else rotate_left(p_parent); _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_parent = p_nd); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == p_parent || p_nd->m_p_right == p_parent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer /*p_nd*/, __gnu_pbds::null_node_update* /*p_update*/) { } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer p_nd, Node_Update_* p_update) { p_update->operator()(& PB_DS_V2F(p_nd->m_value),(p_nd->m_p_left == 0) ? 0 : & PB_DS_V2F(p_nd->m_p_left->m_value),(p_nd->m_p_right == 0) ? 0 : & PB_DS_V2F(p_nd->m_p_right->m_value)); } PB_DS_CLASS_T_DEC template inline void PB_DS_CLASS_C_DEC:: update_to_top(node_pointer p_nd, Node_Update_* p_update) { while (p_nd != m_p_head) { apply_update(p_nd, p_update); p_nd = p_nd->m_p_parent; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_to_top(node_pointer /*p_nd*/, __gnu_pbds::null_node_update* /*p_update*/) { } 8/ext/pb_ds/detail/pat_trie_/r_erase_fn_imps.hpp000064400000005550152526447520015677 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/r_erase_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_node(node_pointer p_z) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_z->m_value))); p_z->~node(); s_node_allocator.deallocate(p_z, 1); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_min_max_for_erased_node(node_pointer p_z) { if (m_size == 1) { m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; return; } if (m_p_head->m_p_left == p_z) { iterator it(p_z); ++it; m_p_head->m_p_left = it.m_p_nd; } else if (m_p_head->m_p_right == p_z) { iterator it(p_z); --it; m_p_head->m_p_right = it.m_p_nd; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { _GLIBCXX_DEBUG_ONLY(assert_valid(true, true);) clear_imp(m_p_head->m_p_parent); m_size = 0; initialize(); _GLIBCXX_DEBUG_ONLY(debug_base::clear();) _GLIBCXX_DEBUG_ONLY(assert_valid(true, true);) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { if (p_nd == 0) return; clear_imp(p_nd->m_p_left); clear_imp(p_nd->m_p_right); p_nd->~Node(); s_node_allocator.deallocate(p_nd, 1); } 8/ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp000064400000034213152526447520016600 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/insert_join_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) branch_bag bag; if (!join_prep(other, bag)) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } m_p_head->m_p_parent = rec_join(m_p_head->m_p_parent, other.m_p_head->m_p_parent, 0, bag); m_p_head->m_p_parent->m_p_parent = m_p_head; m_size += other.m_size; other.initialize(); PB_DS_ASSERT_VALID(other) m_p_head->m_p_min = leftmost_descendant(m_p_head->m_p_parent); m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: join_prep(PB_DS_CLASS_C_DEC& other, branch_bag& r_bag) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (other.m_size == 0) return false; if (m_size == 0) { value_swap(other); return false; } const bool greater = synth_access_traits::cmp_keys(PB_DS_V2F(static_cast(m_p_head->m_p_max)->value()), PB_DS_V2F(static_cast(other.m_p_head->m_p_min)->value())); const bool lesser = synth_access_traits::cmp_keys(PB_DS_V2F(static_cast(other.m_p_head->m_p_max)->value()), PB_DS_V2F(static_cast(m_p_head->m_p_min)->value())); if (!greater && !lesser) __throw_join_error(); rec_join_prep(m_p_head->m_p_parent, other.m_p_head->m_p_parent, r_bag); _GLIBCXX_DEBUG_ONLY(debug_base::join(other, false);) return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(node_const_pointer p_l, node_const_pointer p_r, branch_bag& r_bag) { if (p_l->m_type == leaf_node) { if (p_r->m_type == leaf_node) { rec_join_prep(static_cast(p_l), static_cast(p_r), r_bag); return; } _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node); rec_join_prep(static_cast(p_l), static_cast(p_r), r_bag); return; } _GLIBCXX_DEBUG_ASSERT(p_l->m_type == i_node); if (p_r->m_type == leaf_node) { rec_join_prep(static_cast(p_l), static_cast(p_r), r_bag); return; } _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node); rec_join_prep(static_cast(p_l), static_cast(p_r), r_bag); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(leaf_const_pointer /*p_l*/, leaf_const_pointer /*p_r*/, branch_bag& r_bag) { r_bag.add_branch(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(leaf_const_pointer /*p_l*/, inode_const_pointer /*p_r*/, branch_bag& r_bag) { r_bag.add_branch(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(inode_const_pointer /*p_l*/, leaf_const_pointer /*p_r*/, branch_bag& r_bag) { r_bag.add_branch(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(inode_const_pointer p_l, inode_const_pointer p_r, branch_bag& r_bag) { if (p_l->get_e_ind() == p_r->get_e_ind() && synth_access_traits::equal_prefixes(p_l->pref_b_it(), p_l->pref_e_it(), p_r->pref_b_it(), p_r->pref_e_it())) { for (typename inode::const_iterator it = p_r->begin(); it != p_r->end(); ++ it) { node_const_pointer p_l_join_child = p_l->get_join_child(*it, this); if (p_l_join_child != 0) rec_join_prep(p_l_join_child, * it, r_bag); } return; } if (p_r->get_e_ind() < p_l->get_e_ind() && p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) { node_const_pointer p_r_join_child = p_r->get_join_child(p_l, this); if (p_r_join_child != 0) rec_join_prep(p_r_join_child, p_l, r_bag); return; } if (p_r->get_e_ind() < p_l->get_e_ind() && p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) { node_const_pointer p_r_join_child = p_r->get_join_child(p_l, this); if (p_r_join_child != 0) rec_join_prep(p_r_join_child, p_l, r_bag); return; } r_bag.add_branch(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(node_pointer p_l, node_pointer p_r, size_type checked_ind, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(p_r != 0); if (p_l == 0) { apply_update(p_r, (node_update*)this); return (p_r); } if (p_l->m_type == leaf_node) { if (p_r->m_type == leaf_node) { node_pointer p_ret = rec_join(static_cast(p_l), static_cast(p_r), r_bag); apply_update(p_ret, (node_update*)this); return p_ret; } _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node); node_pointer p_ret = rec_join(static_cast(p_l), static_cast(p_r), checked_ind, r_bag); apply_update(p_ret, (node_update*)this); return p_ret; } _GLIBCXX_DEBUG_ASSERT(p_l->m_type == i_node); if (p_r->m_type == leaf_node) { node_pointer p_ret = rec_join(static_cast(p_l), static_cast(p_r), checked_ind, r_bag); apply_update(p_ret, (node_update*)this); return p_ret; } _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node); node_pointer p_ret = rec_join(static_cast(p_l), static_cast(p_r), r_bag); apply_update(p_ret, (node_update*)this); return p_ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(leaf_pointer p_l, leaf_pointer p_r, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(p_r != 0); if (p_l == 0) return (p_r); node_pointer p_ret = insert_branch(p_l, p_r, r_bag); _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == 2); return p_ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(leaf_pointer p_l, inode_pointer p_r, size_type checked_ind, branch_bag& r_bag) { #ifdef _GLIBCXX_DEBUG const size_type lhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_l); const size_type rhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_r); #endif _GLIBCXX_DEBUG_ASSERT(p_r != 0); node_pointer p_ret = rec_join(p_r, p_l, checked_ind, r_bag); _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == lhs_leafs + rhs_leafs); return p_ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(inode_pointer p_l, leaf_pointer p_r, size_type checked_ind, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(p_l != 0); _GLIBCXX_DEBUG_ASSERT(p_r != 0); #ifdef _GLIBCXX_DEBUG const size_type lhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_l); const size_type rhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_r); #endif if (!p_l->should_be_mine(pref_begin(p_r), pref_end(p_r), checked_ind, this)) { node_pointer p_ret = insert_branch(p_l, p_r, r_bag); PB_DS_ASSERT_NODE_VALID(p_ret) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == lhs_leafs + rhs_leafs); return p_ret; } node_pointer p_pot_child = p_l->add_child(p_r, pref_begin(p_r), pref_end(p_r), this); if (p_pot_child != p_r) { node_pointer p_new_child = rec_join(p_pot_child, p_r, p_l->get_e_ind(), r_bag); p_l->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); } PB_DS_ASSERT_NODE_VALID(p_l) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_l) == lhs_leafs + rhs_leafs); return p_l; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(inode_pointer p_l, inode_pointer p_r, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(p_l != 0); _GLIBCXX_DEBUG_ASSERT(p_r != 0); #ifdef _GLIBCXX_DEBUG const size_type lhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_l); const size_type rhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_r); #endif if (p_l->get_e_ind() == p_r->get_e_ind() && synth_access_traits::equal_prefixes(p_l->pref_b_it(), p_l->pref_e_it(), p_r->pref_b_it(), p_r->pref_e_it())) { for (typename inode::iterator it = p_r->begin(); it != p_r->end(); ++ it) { node_pointer p_new_child = rec_join(p_l->get_join_child(*it, this), * it, 0, r_bag); p_l->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); } p_r->~inode(); s_inode_allocator.deallocate(p_r, 1); PB_DS_ASSERT_NODE_VALID(p_l) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_l) == lhs_leafs + rhs_leafs); return p_l; } if (p_l->get_e_ind() < p_r->get_e_ind() && p_l->should_be_mine(p_r->pref_b_it(), p_r->pref_e_it(), 0, this)) { node_pointer p_new_child = rec_join(p_l->get_join_child(p_r, this), p_r, 0, r_bag); p_l->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); PB_DS_ASSERT_NODE_VALID(p_l) return p_l; } if (p_r->get_e_ind() < p_l->get_e_ind() && p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) { node_pointer p_new_child = rec_join(p_r->get_join_child(p_l, this), p_l, 0, r_bag); p_r->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); PB_DS_ASSERT_NODE_VALID(p_r) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_r) == lhs_leafs + rhs_leafs); return p_r; } node_pointer p_ret = insert_branch(p_l, p_r, r_bag); PB_DS_ASSERT_NODE_VALID(p_ret) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == lhs_leafs + rhs_leafs); return p_ret; } PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert(const_reference r_val) { node_pointer p_lf = find_imp(PB_DS_V2F(r_val)); if (p_lf != 0 && p_lf->m_type == leaf_node && synth_access_traits::equal_keys(PB_DS_V2F(static_cast(p_lf)->value()), PB_DS_V2F(r_val))) { PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(r_val)) PB_DS_ASSERT_VALID((*this)) return std::make_pair(iterator(p_lf), false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_val)) leaf_pointer p_new_lf = s_leaf_allocator.allocate(1); cond_dealtor cond(p_new_lf); new (p_new_lf) leaf(r_val); apply_update(p_new_lf, (node_update*)this); cond.set_call_destructor(); branch_bag bag; bag.add_branch(); m_p_head->m_p_parent = rec_join(m_p_head->m_p_parent, p_new_lf, 0, bag); m_p_head->m_p_parent->m_p_parent = m_p_head; cond.set_no_action_dtor(); ++m_size; update_min_max_for_inserted_leaf(p_new_lf); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) PB_DS_ASSERT_VALID((*this)) return std::make_pair(point_iterator(p_new_lf), true); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: keys_diff_ind(typename access_traits::const_iterator b_l, typename access_traits::const_iterator e_l, typename access_traits::const_iterator b_r, typename access_traits::const_iterator e_r) { size_type diff_pos = 0; while (b_l != e_l) { if (b_r == e_r) return (diff_pos); if (access_traits::e_pos(*b_l) != access_traits::e_pos(*b_r)) return (diff_pos); ++b_l; ++b_r; ++diff_pos; } _GLIBCXX_DEBUG_ASSERT(b_r != e_r); return diff_pos; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::inode_pointer PB_DS_CLASS_C_DEC:: insert_branch(node_pointer p_l, node_pointer p_r, branch_bag& r_bag) { typename synth_access_traits::const_iterator left_b_it = pref_begin(p_l); typename synth_access_traits::const_iterator left_e_it = pref_end(p_l); typename synth_access_traits::const_iterator right_b_it = pref_begin(p_r); typename synth_access_traits::const_iterator right_e_it = pref_end(p_r); const size_type diff_ind = keys_diff_ind(left_b_it, left_e_it, right_b_it, right_e_it); inode_pointer p_new_nd = r_bag.get_branch(); new (p_new_nd) inode(diff_ind, left_b_it); p_new_nd->add_child(p_l, left_b_it, left_e_it, this); p_new_nd->add_child(p_r, right_b_it, right_e_it, this); p_l->m_p_parent = p_new_nd; p_r->m_p_parent = p_new_nd; PB_DS_ASSERT_NODE_VALID(p_new_nd) return (p_new_nd); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: update_min_max_for_inserted_leaf(leaf_pointer p_new_lf) { if (m_p_head->m_p_min == m_p_head || synth_access_traits::cmp_keys(PB_DS_V2F(p_new_lf->value()), PB_DS_V2F(static_cast(m_p_head->m_p_min)->value()))) m_p_head->m_p_min = p_new_lf; if (m_p_head->m_p_max == m_p_head || synth_access_traits::cmp_keys(PB_DS_V2F(static_cast(m_p_head->m_p_max)->value()), PB_DS_V2F(p_new_lf->value()))) m_p_head->m_p_max = p_new_lf; } 8/ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp000064400000017055152526447520015415 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/split_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) branch_bag bag; leaf_pointer p_split_lf = split_prep(r_key, other, bag); if (p_split_lf == 0) { _GLIBCXX_DEBUG_ASSERT(bag.empty()); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } _GLIBCXX_DEBUG_ASSERT(!bag.empty()); other.clear(); m_p_head->m_p_parent = rec_split(m_p_head->m_p_parent, pref_begin(p_split_lf), pref_end(p_split_lf), other, bag); m_p_head->m_p_parent->m_p_parent = m_p_head; head_pointer __ohead = other.m_p_head; __ohead->m_p_max = m_p_head->m_p_max; m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); __ohead->m_p_min = other.leftmost_descendant(__ohead->m_p_parent); other.m_size = std::distance(other.PB_DS_CLASS_C_DEC::begin(), other.PB_DS_CLASS_C_DEC::end()); m_size -= other.m_size; PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: split_prep(key_const_reference r_key, PB_DS_CLASS_C_DEC& other, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(r_bag.empty()); if (m_size == 0) { other.clear(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return 0; } if (synth_access_traits::cmp_keys(r_key, PB_DS_V2F(static_cast(m_p_head->m_p_min)->value()))) { other.clear(); value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return 0; } if (!synth_access_traits::cmp_keys(r_key, PB_DS_V2F(static_cast(m_p_head->m_p_max)->value()))) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return 0; } iterator it = lower_bound(r_key); if (!synth_access_traits::equal_keys(PB_DS_V2F(*it), r_key)) --it; node_pointer p_nd = it.m_p_nd; _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == leaf_node); leaf_pointer p_ret_l = static_cast(p_nd); while (p_nd->m_type != head_node) { r_bag.add_branch(); p_nd = p_nd->m_p_parent; } _GLIBCXX_DEBUG_ONLY(debug_base::split(r_key,(synth_access_traits&)(*this), other);) return p_ret_l; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_split(node_pointer p_nd, a_const_iterator b_it, a_const_iterator e_it, PB_DS_CLASS_C_DEC& other, branch_bag& r_bag) { if (p_nd->m_type == leaf_node) { _GLIBCXX_DEBUG_ASSERT(other.m_p_head->m_p_parent == 0); return p_nd; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); inode_pointer p_ind = static_cast(p_nd); node_pointer pfirst = p_ind->get_child_node(b_it, e_it, this); node_pointer p_child_ret = rec_split(pfirst, b_it, e_it, other, r_bag); PB_DS_ASSERT_NODE_VALID(p_child_ret) p_ind->replace_child(p_child_ret, b_it, e_it, this); apply_update(p_ind, (node_update*)this); inode_iterator child_it = p_ind->get_child_it(b_it, e_it, this); const size_type lhs_dist = std::distance(p_ind->begin(), child_it); const size_type lhs_num_children = lhs_dist + 1; _GLIBCXX_DEBUG_ASSERT(lhs_num_children > 0); const size_type rhs_dist = std::distance(p_ind->begin(), p_ind->end()); size_type rhs_num_children = rhs_dist - lhs_num_children; if (rhs_num_children == 0) { apply_update(p_ind, (node_update*)this); return p_ind; } other.split_insert_branch(p_ind->get_e_ind(), b_it, child_it, rhs_num_children, r_bag); child_it = p_ind->get_child_it(b_it, e_it, this); while (rhs_num_children != 0) { ++child_it; p_ind->remove_child(child_it); --rhs_num_children; } apply_update(p_ind, (node_update*)this); const size_type int_dist = std::distance(p_ind->begin(), p_ind->end()); _GLIBCXX_DEBUG_ASSERT(int_dist >= 1); if (int_dist > 1) { p_ind->update_prefixes(this); PB_DS_ASSERT_NODE_VALID(p_ind) apply_update(p_ind, (node_update*)this); return p_ind; } node_pointer p_ret = *p_ind->begin(); p_ind->~inode(); s_inode_allocator.deallocate(p_ind, 1); apply_update(p_ret, (node_update*)this); return p_ret; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split_insert_branch(size_type e_ind, a_const_iterator b_it, inode_iterator child_b_it, size_type num_children, branch_bag& r_bag) { #ifdef _GLIBCXX_DEBUG if (m_p_head->m_p_parent != 0) PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent) #endif const size_type start = m_p_head->m_p_parent == 0 ? 0 : 1; const size_type total_num_children = start + num_children; if (total_num_children == 0) { _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == 0); return; } if (total_num_children == 1) { if (m_p_head->m_p_parent != 0) { PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent) return; } _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == 0); ++child_b_it; m_p_head->m_p_parent = *child_b_it; m_p_head->m_p_parent->m_p_parent = m_p_head; apply_update(m_p_head->m_p_parent, (node_update*)this); PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent) return; } _GLIBCXX_DEBUG_ASSERT(total_num_children > 1); inode_pointer p_new_root = r_bag.get_branch(); new (p_new_root) inode(e_ind, b_it); size_type num_inserted = 0; while (num_inserted++ < num_children) { ++child_b_it; PB_DS_ASSERT_NODE_VALID((*child_b_it)) p_new_root->add_child(*child_b_it, pref_begin(*child_b_it), pref_end(*child_b_it), this); } if (m_p_head->m_p_parent != 0) p_new_root->add_child(m_p_head->m_p_parent, pref_begin(m_p_head->m_p_parent), pref_end(m_p_head->m_p_parent), this); m_p_head->m_p_parent = p_new_root; p_new_root->m_p_parent = m_p_head; apply_update(m_p_head->m_p_parent, (node_update*)this); PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent) } 8/ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp000064400000006511152526447520015353 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/trace_fn_imps.hpp * Contains an implementation class for pat_trie_. */ #ifdef PB_DS_PAT_TRIE_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << std::endl; if (m_p_head->m_p_parent == 0) return; trace_node(m_p_head->m_p_parent, 0); std::cerr << std::endl; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node(node_const_pointer p_nd, size_type level) { for (size_type i = 0; i < level; ++i) std::cerr << ' '; std::cerr << p_nd << " "; std::cerr << ((p_nd->m_type == pat_trie_leaf_node_type) ? "l " : "i "); trace_node_metadata(p_nd, type_to_type()); typename access_traits::const_iterator el_it = pref_begin(p_nd); while (el_it != pref_end(p_nd)) { std::cerr <<* el_it; ++el_it; } if (p_nd->m_type == pat_trie_leaf_node_type) { std::cerr << std::endl; return; } inode_const_pointer p_internal = static_cast(p_nd); std::cerr << " " << static_cast(p_internal->get_e_ind()) << std::endl; const size_type num_children = std::distance(p_internal->begin(), p_internal->end()); for (size_type child_i = 0; child_i < num_children; ++child_i) { typename inode::const_iterator child_it = p_internal->begin(); std::advance(child_it, num_children - child_i - 1); trace_node(*child_it, level + 1); } } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: trace_node_metadata(node_const_pointer p_nd, type_to_type) { std::cerr << "(" << static_cast(p_nd->get_metadata()) << ") "; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node_metadata(node_const_pointer, type_to_type) { } #endif 8/ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp000064400000004247152526447520017101 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/policy_access_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::access_traits& PB_DS_CLASS_C_DEC:: get_access_traits() { return *this; } PB_DS_CLASS_T_DEC const typename PB_DS_CLASS_C_DEC::access_traits& PB_DS_CLASS_C_DEC:: get_access_traits() const { return *this; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_update& PB_DS_CLASS_C_DEC:: get_node_update() { return *this; } PB_DS_CLASS_T_DEC const typename PB_DS_CLASS_C_DEC::node_update& PB_DS_CLASS_C_DEC:: get_node_update() const { return *this; } 8/ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp000064400000013120152526447520021275 0ustar00 // -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/constructors_destructor_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::head_allocator PB_DS_CLASS_C_DEC::s_head_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::inode_allocator PB_DS_CLASS_C_DEC::s_inode_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_allocator PB_DS_CLASS_C_DEC::s_leaf_allocator; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_PAT_TRIE_NAME() : m_p_head(s_head_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_PAT_TRIE_NAME(const access_traits& r_access_traits) : synth_access_traits(r_access_traits), m_p_head(s_head_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_PAT_TRIE_NAME(const PB_DS_CLASS_C_DEC& other) : #ifdef _GLIBCXX_DEBUG debug_base(other), #endif synth_access_traits(other), node_update(other), m_p_head(s_head_allocator.allocate(1)), m_size(0) { initialize(); m_size = other.m_size; PB_DS_ASSERT_VALID(other) if (other.m_p_head->m_p_parent == 0) { PB_DS_ASSERT_VALID((*this)) return; } __try { m_p_head->m_p_parent = recursive_copy_node(other.m_p_head->m_p_parent); } __catch(...) { s_head_allocator.deallocate(m_p_head, 1); __throw_exception_again; } m_p_head->m_p_min = leftmost_descendant(m_p_head->m_p_parent); m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); m_p_head->m_p_parent->m_p_parent = m_p_head; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) value_swap(other); std::swap((access_traits& )(*this), (access_traits& )other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);) std::swap(m_p_head, other.m_p_head); std::swap(m_size, other.m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_PAT_TRIE_NAME() { clear(); s_head_allocator.deallocate(m_p_head, 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { new (m_p_head) head(); m_p_head->m_p_parent = 0; m_p_head->m_p_min = m_p_head; m_p_head->m_p_max = m_p_head; m_size = 0; } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: recursive_copy_node(node_const_pointer p_ncp) { _GLIBCXX_DEBUG_ASSERT(p_ncp != 0); if (p_ncp->m_type == leaf_node) { leaf_const_pointer p_other_lf = static_cast(p_ncp); leaf_pointer p_new_lf = s_leaf_allocator.allocate(1); cond_dealtor cond(p_new_lf); new (p_new_lf) leaf(p_other_lf->value()); apply_update(p_new_lf, (node_update*)this); cond.set_no_action_dtor(); return (p_new_lf); } _GLIBCXX_DEBUG_ASSERT(p_ncp->m_type == i_node); node_pointer a_p_children[inode::arr_size]; size_type child_i = 0; inode_const_pointer p_icp = static_cast(p_ncp); typename inode::const_iterator child_it = p_icp->begin(); inode_pointer p_ret; __try { while (child_it != p_icp->end()) { a_p_children[child_i] = recursive_copy_node(*(child_it)); child_i++; child_it++; } p_ret = s_inode_allocator.allocate(1); } __catch(...) { while (child_i-- > 0) clear_imp(a_p_children[child_i]); __throw_exception_again; } new (p_ret) inode(p_icp->get_e_ind(), pref_begin(a_p_children[0])); --child_i; _GLIBCXX_DEBUG_ASSERT(child_i >= 1); do p_ret->add_child(a_p_children[child_i], pref_begin(a_p_children[child_i]), pref_end(a_p_children[child_i]), this); while (child_i-- > 0); apply_update(p_ret, (node_update*)this); return p_ret; } 8/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp000064400000004010152526447520015200 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/info_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (m_size == 0); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_size; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_inode_allocator.max_size(); } 8/ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp000064400000017303152526447520015176 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/find_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = find_imp(r_key); if (p_nd == 0 || p_nd->m_type != leaf_node) { PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } if (synth_access_traits::equal_keys(PB_DS_V2F(static_cast(p_nd)->value()), r_key)) { PB_DS_CHECK_KEY_EXISTS(r_key) return iterator(p_nd); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) node_const_pointer p_nd = const_cast(this)->find_imp(r_key); if (p_nd == 0 || p_nd->m_type != leaf_node) { PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } if (synth_access_traits::equal_keys(PB_DS_V2F(static_cast(p_nd)->value()), r_key)) { PB_DS_CHECK_KEY_EXISTS(r_key) return const_iterator(const_cast(p_nd)); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: find_imp(key_const_reference r_key) { if (empty()) return 0; typename synth_access_traits::const_iterator b_it = synth_access_traits::begin(r_key); typename synth_access_traits::const_iterator e_it = synth_access_traits::end(r_key); node_pointer p_nd = m_p_head->m_p_parent; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); while (p_nd->m_type != leaf_node) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); node_pointer p_next_nd = static_cast(p_nd)->get_child_node(b_it, e_it, this); if (p_next_nd == 0) return p_nd; p_nd = p_next_nd; } return p_nd; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: lower_bound_imp(key_const_reference r_key) { if (empty()) return (m_p_head); node_pointer p_nd = m_p_head->m_p_parent; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); typename PB_DS_CLASS_C_DEC::a_const_iterator b_it = synth_access_traits::begin(r_key); typename PB_DS_CLASS_C_DEC::a_const_iterator e_it = synth_access_traits::end(r_key); size_type checked_ind = 0; while (true) { if (p_nd->m_type == leaf_node) { if (!synth_access_traits::cmp_keys(PB_DS_V2F(static_cast(p_nd)->value()), r_key)) return p_nd; iterator it(p_nd); ++it; return it.m_p_nd; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); const size_type new_checked_ind = static_cast(p_nd)->get_e_ind(); p_nd = static_cast(p_nd)->get_lower_bound_child_node( b_it, e_it, checked_ind, this); checked_ind = new_checked_ind; } } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: lower_bound(key_const_reference r_key) { return point_iterator(lower_bound_imp(r_key)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: lower_bound(key_const_reference r_key) const { return point_const_iterator(const_cast(this)->lower_bound_imp(r_key)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: upper_bound(key_const_reference r_key) { point_iterator l_bound_it = lower_bound(r_key); _GLIBCXX_DEBUG_ASSERT(l_bound_it == end() || !synth_access_traits::cmp_keys(PB_DS_V2F(*l_bound_it), r_key)); if (l_bound_it == end() || synth_access_traits::cmp_keys(r_key, PB_DS_V2F(*l_bound_it))) return l_bound_it; return ++l_bound_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: upper_bound(key_const_reference r_key) const { point_const_iterator l_bound_it = lower_bound(r_key); _GLIBCXX_DEBUG_ASSERT(l_bound_it == end() || !synth_access_traits::cmp_keys(PB_DS_V2F(*l_bound_it), r_key)); if (l_bound_it == end() || synth_access_traits::cmp_keys(r_key, PB_DS_V2F(*l_bound_it))) return l_bound_it; return ++l_bound_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::a_const_iterator PB_DS_CLASS_C_DEC:: pref_begin(node_const_pointer p_nd) { if (p_nd->m_type == leaf_node) return (synth_access_traits::begin(PB_DS_V2F(static_cast(p_nd)->value()))); _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); return static_cast(p_nd)->pref_b_it(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::a_const_iterator PB_DS_CLASS_C_DEC:: pref_end(node_const_pointer p_nd) { if (p_nd->m_type == leaf_node) return (synth_access_traits::end(PB_DS_V2F(static_cast(p_nd)->value()))); _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); return static_cast(p_nd)->pref_e_it(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::leaf_const_pointer PB_DS_CLASS_C_DEC:: leftmost_descendant(node_const_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast(p_nd); return static_cast(p_nd)->leftmost_descendant(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: leftmost_descendant(node_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast(p_nd); return static_cast(p_nd)->leftmost_descendant(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::leaf_const_pointer PB_DS_CLASS_C_DEC:: rightmost_descendant(node_const_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast(p_nd); return static_cast(p_nd)->rightmost_descendant(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: rightmost_descendant(node_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast(p_nd); return static_cast(p_nd)->rightmost_descendant(); } 8/ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp000064400000006630152526447520016273 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/iterators_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { return iterator(m_p_head->m_p_min); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { return const_iterator(m_p_head->m_p_min); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return iterator(m_p_head); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return const_iterator(m_p_head); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: rbegin() const { if (empty()) return rend(); return --end(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: rbegin() { if (empty()) return rend(); return --end(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: rend() { return reverse_iterator(m_p_head); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: rend() const { return const_reverse_iterator(m_p_head); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_begin() const { return node_const_iterator(m_p_head->m_p_parent, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_begin() { return node_iterator(m_p_head->m_p_parent, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_end() const { return node_const_iterator(0, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_end() { return node_iterator(0, this); } 8/ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp000064400000007317152526447520015350 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/debug_fn_imps.hpp * Contains an implementation class for pat_trie_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { if (m_p_head->m_p_parent != 0) m_p_head->m_p_parent->assert_valid(this, __file, __line); assert_iterators(__file, __line); assert_reverse_iterators(__file, __line); if (m_p_head->m_p_parent == 0) { PB_DS_DEBUG_VERIFY(m_p_head->m_p_min == m_p_head); PB_DS_DEBUG_VERIFY(m_p_head->m_p_max == m_p_head); PB_DS_DEBUG_VERIFY(empty()); return; } PB_DS_DEBUG_VERIFY(m_p_head->m_p_min->m_type == leaf_node); PB_DS_DEBUG_VERIFY(m_p_head->m_p_max->m_type == leaf_node); PB_DS_DEBUG_VERIFY(!empty()); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_iterators(const char* __file, int __line) const { size_type calc_size = 0; for (const_iterator it = begin(); it != end(); ++it) { ++calc_size; debug_base::check_key_exists(PB_DS_V2F(*it), __file, __line); PB_DS_DEBUG_VERIFY(lower_bound(PB_DS_V2F(*it)) == it); PB_DS_DEBUG_VERIFY(--upper_bound(PB_DS_V2F(*it)) == it); } PB_DS_DEBUG_VERIFY(calc_size == m_size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_reverse_iterators(const char* __file, int __line) const { size_type calc_size = 0; for (const_reverse_iterator it = rbegin(); it != rend(); ++it) { ++calc_size; node_const_pointer p_nd = const_cast(this)->find_imp(PB_DS_V2F(*it)); PB_DS_DEBUG_VERIFY(p_nd == it.m_p_nd); } PB_DS_DEBUG_VERIFY(calc_size == m_size); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: recursive_count_leafs(node_const_pointer p_nd, const char* __file, int __line) { if (p_nd == 0) return (0); if (p_nd->m_type == leaf_node) return (1); PB_DS_DEBUG_VERIFY(p_nd->m_type == i_node); size_type ret = 0; for (typename inode::const_iterator it = static_cast(p_nd)->begin(); it != static_cast(p_nd)->end(); ++it) ret += recursive_count_leafs(*it, __file, __line); return ret; } #endif 8/ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp000064400000017411152526447520015355 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/erase_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { node_pointer p_nd = find_imp(r_key); if (p_nd == 0 || p_nd->m_type == i_node) { PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return false; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == leaf_node); if (!synth_access_traits::equal_keys(PB_DS_V2F(reinterpret_cast(p_nd)->value()), r_key)) { PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return false; } PB_DS_CHECK_KEY_EXISTS(r_key) erase_leaf(static_cast(p_nd)); PB_DS_ASSERT_VALID((*this)) return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_fixup(inode_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(std::distance(p_nd->begin(), p_nd->end()) >= 1); if (std::distance(p_nd->begin(), p_nd->end()) == 1) { node_pointer p_parent = p_nd->m_p_parent; if (p_parent == m_p_head) m_p_head->m_p_parent = *p_nd->begin(); else { _GLIBCXX_DEBUG_ASSERT(p_parent->m_type == i_node); node_pointer p_new_child = *p_nd->begin(); typedef inode_pointer inode_ptr; inode_ptr p_internal = static_cast(p_parent); p_internal->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); } (*p_nd->begin())->m_p_parent = p_nd->m_p_parent; p_nd->~inode(); s_inode_allocator.deallocate(p_nd, 1); if (p_parent == m_p_head) return; _GLIBCXX_DEBUG_ASSERT(p_parent->m_type == i_node); p_nd = static_cast(p_parent); } while (true) { _GLIBCXX_DEBUG_ASSERT(std::distance(p_nd->begin(), p_nd->end()) > 1); p_nd->update_prefixes(this); apply_update(p_nd, (node_update*)this); PB_DS_ASSERT_NODE_VALID(p_nd) if (p_nd->m_p_parent->m_type == head_node) return; _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_parent->m_type == i_node); p_nd = static_cast(p_nd->m_p_parent); } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_leaf(leaf_pointer p_l) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_l->value()))); p_l->~leaf(); s_leaf_allocator.deallocate(p_l, 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { if (!empty()) { clear_imp(m_p_head->m_p_parent); m_size = 0; initialize(); _GLIBCXX_DEBUG_ONLY(debug_base::clear();) PB_DS_ASSERT_VALID((*this)) } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { if (p_nd->m_type == i_node) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); for (typename inode::iterator it = static_cast(p_nd)->begin(); it != static_cast(p_nd)->end(); ++it) { node_pointer p_child =* it; clear_imp(p_child); } s_inode_allocator.deallocate(static_cast(p_nd), 1); return; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == leaf_node); static_cast(p_nd)->~leaf(); s_leaf_allocator.deallocate(static_cast(p_nd), 1); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: erase(const_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it == end()) return it; const_iterator ret_it = it; ++ret_it; _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node); erase_leaf(static_cast(it.m_p_nd)); PB_DS_ASSERT_VALID((*this)) return ret_it; } #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: erase(iterator it) { PB_DS_ASSERT_VALID((*this)) if (it == end()) return it; iterator ret_it = it; ++ret_it; _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node); erase_leaf(static_cast(it.m_p_nd)); PB_DS_ASSERT_VALID((*this)) return ret_it; } #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: erase(const_reverse_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it.m_p_nd == m_p_head) return it; const_reverse_iterator ret_it = it; ++ret_it; _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node); erase_leaf(static_cast(it.m_p_nd)); PB_DS_ASSERT_VALID((*this)) return ret_it; } #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: erase(reverse_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it.m_p_nd == m_p_head) return it; reverse_iterator ret_it = it; ++ret_it; _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node); erase_leaf(static_cast(it.m_p_nd)); PB_DS_ASSERT_VALID((*this)) return ret_it; } #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { size_type num_ersd = 0; PB_DS_ASSERT_VALID((*this)) iterator it = begin(); while (it != end()) { PB_DS_ASSERT_VALID((*this)) if (pred(*it)) { ++num_ersd; it = erase(it); } else ++it; } PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_leaf(leaf_pointer p_l) { update_min_max_for_erased_leaf(p_l); if (p_l->m_p_parent->m_type == head_node) { _GLIBCXX_DEBUG_ASSERT(size() == 1); clear(); return; } _GLIBCXX_DEBUG_ASSERT(size() > 1); _GLIBCXX_DEBUG_ASSERT(p_l->m_p_parent->m_type == i_node); inode_pointer p_parent = static_cast(p_l->m_p_parent); p_parent->remove_child(p_l); erase_fixup(p_parent); actual_erase_leaf(p_l); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: update_min_max_for_erased_leaf(leaf_pointer p_l) { if (m_size == 1) { m_p_head->m_p_min = m_p_head; m_p_head->m_p_max = m_p_head; return; } if (p_l == static_cast(m_p_head->m_p_min)) { iterator it(p_l); ++it; m_p_head->m_p_min = it.m_p_nd; return; } if (p_l == static_cast(m_p_head->m_p_max)) { iterator it(p_l); --it; m_p_head->m_p_max = it.m_p_nd; } } 8/ext/pb_ds/detail/pat_trie_/synth_access_traits.hpp000064400000015076152526447520016624 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/synth_access_traits.hpp * Contains an implementation class for a patricia tree. */ #ifndef PB_DS_SYNTH_E_ACCESS_TRAITS_HPP #define PB_DS_SYNTH_E_ACCESS_TRAITS_HPP #include namespace __gnu_pbds { namespace detail { #define PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC \ template #define PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC \ synth_access_traits /// Synthetic element access traits. template struct synth_access_traits : public _ATraits { typedef _ATraits base_type; typedef typename base_type::const_iterator const_iterator; typedef Type_Traits type_traits; typedef typename type_traits::const_reference const_reference; typedef typename type_traits::key_const_reference key_const_reference; synth_access_traits(); synth_access_traits(const base_type&); inline bool equal_prefixes(const_iterator, const_iterator, const_iterator, const_iterator, bool compare_after = true) const; bool equal_keys(key_const_reference, key_const_reference) const; bool cmp_prefixes(const_iterator, const_iterator, const_iterator, const_iterator, bool compare_after = false) const; bool cmp_keys(key_const_reference, key_const_reference) const; inline static key_const_reference extract_key(const_reference); #ifdef _GLIBCXX_DEBUG bool operator()(key_const_reference, key_const_reference); #endif private: inline static key_const_reference extract_key(const_reference, true_type); inline static key_const_reference extract_key(const_reference, false_type); static integral_constant s_set_ind; }; PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC integral_constant PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::s_set_ind; PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: synth_access_traits() { } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: synth_access_traits(const _ATraits& r_traits) : _ATraits(r_traits) { } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC inline bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: equal_prefixes(const_iterator b_l, const_iterator e_l, const_iterator b_r, const_iterator e_r, bool compare_after /*= false */) const { while (b_l != e_l) { if (b_r == e_r) return false; if (base_type::e_pos(*b_l) != base_type::e_pos(*b_r)) return false; ++b_l; ++b_r; } return (!compare_after || b_r == e_r); } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: equal_keys(key_const_reference r_lhs_key, key_const_reference r_rhs_key) const { return equal_prefixes(base_type::begin(r_lhs_key), base_type::end(r_lhs_key), base_type::begin(r_rhs_key), base_type::end(r_rhs_key), true); } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: cmp_prefixes(const_iterator b_l, const_iterator e_l, const_iterator b_r, const_iterator e_r, bool compare_after /* = false*/) const { while (b_l != e_l) { if (b_r == e_r) return false; const typename base_type::size_type l_pos = base_type::e_pos(*b_l); const typename base_type::size_type r_pos = base_type::e_pos(*b_r); if (l_pos != r_pos) return l_pos < r_pos; ++b_l; ++b_r; } if (!compare_after) return false; return b_r != e_r; } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: cmp_keys(key_const_reference r_lhs_key, key_const_reference r_rhs_key) const { return cmp_prefixes(base_type::begin(r_lhs_key), base_type::end(r_lhs_key), base_type::begin(r_rhs_key), base_type::end(r_rhs_key), true); } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::key_const_reference PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: extract_key(const_reference r_val) { return extract_key(r_val, s_set_ind); } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::key_const_reference PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: extract_key(const_reference r_val, true_type) { return r_val; } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::key_const_reference PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: extract_key(const_reference r_val, false_type) { return r_val.first; } #ifdef _GLIBCXX_DEBUG PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: operator()(key_const_reference r_lhs, key_const_reference r_rhs) { return cmp_keys(r_lhs, r_rhs); } #endif #undef PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC #undef PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/pat_trie_/pat_trie_base.hpp000064400000111401152526447520015336 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/pat_trie_base.hpp * Contains the base class for a patricia tree. */ #ifndef PB_DS_PAT_TRIE_BASE #define PB_DS_PAT_TRIE_BASE #include namespace __gnu_pbds { namespace detail { /// Base type for PATRICIA trees. struct pat_trie_base { /** * @brief Three types of nodes. * * i_node is used by _Inode, leaf_node by _Leaf, and head_node by _Head. */ enum node_type { i_node, leaf_node, head_node }; /// Metadata base primary template. template struct _Metadata { typedef Metadata metadata_type; typedef _Alloc allocator_type; typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other::const_reference const_reference; const_reference get_metadata() const { return m_metadata; } metadata_type m_metadata; }; /// Specialization for null metadata. template struct _Metadata { typedef null_type metadata_type; typedef _Alloc allocator_type; }; /// Node base. template struct _Node_base : public Metadata { private: typedef typename Metadata::allocator_type _Alloc; public: typedef _Alloc allocator_type; typedef _ATraits access_traits; typedef typename _ATraits::type_traits type_traits; typedef typename _Alloc::template rebind<_Node_base> __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; node_pointer m_p_parent; const node_type m_type; _Node_base(node_type type) : m_type(type) { } typedef typename _Alloc::template rebind<_ATraits> __rebind_at; typedef typename __rebind_at::other::const_pointer a_const_pointer; typedef typename _ATraits::const_iterator a_const_iterator; #ifdef _GLIBCXX_DEBUG typedef std::pair node_debug_info; void assert_valid(a_const_pointer p_traits, const char* __file, int __line) const { assert_valid_imp(p_traits, __file, __line); } virtual node_debug_info assert_valid_imp(a_const_pointer, const char*, int) const = 0; #endif }; /// Head node for PATRICIA tree. template struct _Head : public _Node_base<_ATraits, Metadata> { typedef _Node_base<_ATraits, Metadata> base_type; typedef typename base_type::type_traits type_traits; typedef typename base_type::node_pointer node_pointer; node_pointer m_p_min; node_pointer m_p_max; _Head() : base_type(head_node) { } #ifdef _GLIBCXX_DEBUG typedef typename base_type::node_debug_info node_debug_info; typedef typename base_type::a_const_pointer a_const_pointer; virtual node_debug_info assert_valid_imp(a_const_pointer, const char* __file, int __line) const { _GLIBCXX_DEBUG_VERIFY_AT(false, _M_message("Assertion from %1;:%2;") ._M_string(__FILE__)._M_integer(__LINE__), __file, __line); return node_debug_info(); } #endif }; /// Leaf node for PATRICIA tree. template struct _Leaf : public _Node_base<_ATraits, Metadata> { typedef _Node_base<_ATraits, Metadata> base_type; typedef typename base_type::type_traits type_traits; typedef typename type_traits::value_type value_type; typedef typename type_traits::reference reference; typedef typename type_traits::const_reference const_reference; private: value_type m_value; _Leaf(const _Leaf&); public: _Leaf(const_reference other) : base_type(leaf_node), m_value(other) { } reference value() { return m_value; } const_reference value() const { return m_value; } #ifdef _GLIBCXX_DEBUG typedef typename base_type::node_debug_info node_debug_info; typedef typename base_type::a_const_pointer a_const_pointer; virtual node_debug_info assert_valid_imp(a_const_pointer p_traits, const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(base_type::m_type == leaf_node); node_debug_info ret; const_reference r_val = value(); return std::make_pair(p_traits->begin(p_traits->extract_key(r_val)), p_traits->end(p_traits->extract_key(r_val))); } virtual ~_Leaf() { } #endif }; /// Internal node type, PATRICIA tree. template struct _Inode : public _Node_base<_ATraits, Metadata> { typedef _Node_base<_ATraits, Metadata> base_type; typedef typename base_type::type_traits type_traits; typedef typename base_type::access_traits access_traits; typedef typename type_traits::value_type value_type; typedef typename base_type::allocator_type _Alloc; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; private: typedef typename base_type::a_const_pointer a_const_pointer; typedef typename base_type::a_const_iterator a_const_iterator; typedef typename base_type::node_pointer node_pointer; typedef typename _Alloc::template rebind __rebind_n; typedef typename __rebind_n::other::const_pointer node_const_pointer; typedef _Leaf<_ATraits, Metadata> leaf; typedef typename _Alloc::template rebind::other __rebind_l; typedef typename __rebind_l::pointer leaf_pointer; typedef typename __rebind_l::const_pointer leaf_const_pointer; typedef typename _Alloc::template rebind<_Inode>::other __rebind_in; typedef typename __rebind_in::pointer inode_pointer; typedef typename __rebind_in::const_pointer inode_const_pointer; inline size_type get_pref_pos(a_const_iterator, a_const_iterator, a_const_pointer) const; public: typedef typename _Alloc::template rebind::other __rebind_np; typedef typename __rebind_np::pointer node_pointer_pointer; typedef typename __rebind_np::reference node_pointer_reference; enum { arr_size = _ATraits::max_size + 1 }; PB_DS_STATIC_ASSERT(min_arr_size, arr_size >= 2); /// Constant child iterator. struct const_iterator { node_pointer_pointer m_p_p_cur; node_pointer_pointer m_p_p_end; typedef std::forward_iterator_tag iterator_category; typedef typename _Alloc::difference_type difference_type; typedef node_pointer value_type; typedef node_pointer_pointer pointer; typedef node_pointer_reference reference; const_iterator(node_pointer_pointer p_p_cur = 0, node_pointer_pointer p_p_end = 0) : m_p_p_cur(p_p_cur), m_p_p_end(p_p_end) { } bool operator==(const const_iterator& other) const { return m_p_p_cur == other.m_p_p_cur; } bool operator!=(const const_iterator& other) const { return m_p_p_cur != other.m_p_p_cur; } const_iterator& operator++() { do ++m_p_p_cur; while (m_p_p_cur != m_p_p_end && *m_p_p_cur == 0); return *this; } const_iterator operator++(int) { const_iterator ret_it(*this); operator++(); return ret_it; } const node_pointer_pointer operator->() const { _GLIBCXX_DEBUG_ONLY(assert_referencible();) return m_p_p_cur; } node_const_pointer operator*() const { _GLIBCXX_DEBUG_ONLY(assert_referencible();) return *m_p_p_cur; } protected: #ifdef _GLIBCXX_DEBUG void assert_referencible() const { _GLIBCXX_DEBUG_ASSERT(m_p_p_cur != m_p_p_end && *m_p_p_cur != 0); } #endif }; /// Child iterator. struct iterator : public const_iterator { public: typedef std::forward_iterator_tag iterator_category; typedef typename _Alloc::difference_type difference_type; typedef node_pointer value_type; typedef node_pointer_pointer pointer; typedef node_pointer_reference reference; inline iterator(node_pointer_pointer p_p_cur = 0, node_pointer_pointer p_p_end = 0) : const_iterator(p_p_cur, p_p_end) { } bool operator==(const iterator& other) const { return const_iterator::m_p_p_cur == other.m_p_p_cur; } bool operator!=(const iterator& other) const { return const_iterator::m_p_p_cur != other.m_p_p_cur; } iterator& operator++() { const_iterator::operator++(); return *this; } iterator operator++(int) { iterator ret_it(*this); operator++(); return ret_it; } node_pointer_pointer operator->() { _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();) return const_iterator::m_p_p_cur; } node_pointer operator*() { _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();) return *const_iterator::m_p_p_cur; } }; _Inode(size_type, const a_const_iterator); void update_prefixes(a_const_pointer); const_iterator begin() const; iterator begin(); const_iterator end() const; iterator end(); inline node_pointer get_child_node(a_const_iterator, a_const_iterator, a_const_pointer); inline node_const_pointer get_child_node(a_const_iterator, a_const_iterator, a_const_pointer) const; inline iterator get_child_it(a_const_iterator, a_const_iterator, a_const_pointer); inline node_pointer get_lower_bound_child_node(a_const_iterator, a_const_iterator, size_type, a_const_pointer); inline node_pointer add_child(node_pointer, a_const_iterator, a_const_iterator, a_const_pointer); inline node_const_pointer get_join_child(node_const_pointer, a_const_pointer) const; inline node_pointer get_join_child(node_pointer, a_const_pointer); void remove_child(node_pointer); void remove_child(iterator); void replace_child(node_pointer, a_const_iterator, a_const_iterator, a_const_pointer); inline a_const_iterator pref_b_it() const; inline a_const_iterator pref_e_it() const; bool should_be_mine(a_const_iterator, a_const_iterator, size_type, a_const_pointer) const; leaf_pointer leftmost_descendant(); leaf_const_pointer leftmost_descendant() const; leaf_pointer rightmost_descendant(); leaf_const_pointer rightmost_descendant() const; #ifdef _GLIBCXX_DEBUG typedef typename base_type::node_debug_info node_debug_info; virtual node_debug_info assert_valid_imp(a_const_pointer, const char*, int) const; #endif size_type get_e_ind() const { return m_e_ind; } private: _Inode(const _Inode&); size_type get_begin_pos() const; static __rebind_l s_leaf_alloc; static __rebind_in s_inode_alloc; const size_type m_e_ind; a_const_iterator m_pref_b_it; a_const_iterator m_pref_e_it; node_pointer m_a_p_children[arr_size]; }; #define PB_DS_CONST_IT_C_DEC \ _CIter #define PB_DS_CONST_ODIR_IT_C_DEC \ _CIter #define PB_DS_IT_C_DEC \ _Iter #define PB_DS_ODIR_IT_C_DEC \ _Iter /// Const iterator. template class _CIter { public: // These types are all the same for the first four template arguments. typedef typename Node::allocator_type allocator_type; typedef typename Node::type_traits type_traits; typedef std::bidirectional_iterator_tag iterator_category; typedef typename allocator_type::difference_type difference_type; typedef typename type_traits::value_type value_type; typedef typename type_traits::pointer pointer; typedef typename type_traits::reference reference; typedef typename type_traits::const_pointer const_pointer; typedef typename type_traits::const_reference const_reference; typedef allocator_type _Alloc; typedef typename _Alloc::template rebind __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; typedef typename _Alloc::template rebind __rebind_l; typedef typename __rebind_l::other::pointer leaf_pointer; typedef typename __rebind_l::other::const_pointer leaf_const_pointer; typedef typename _Alloc::template rebind __rebind_h; typedef typename __rebind_h::other::pointer head_pointer; typedef typename _Alloc::template rebind __rebind_in; typedef typename __rebind_in::other::pointer inode_pointer; typedef typename Inode::iterator inode_iterator; node_pointer m_p_nd; _CIter(node_pointer p_nd = 0) : m_p_nd(p_nd) { } _CIter(const PB_DS_CONST_ODIR_IT_C_DEC& other) : m_p_nd(other.m_p_nd) { } _CIter& operator=(const _CIter& other) { m_p_nd = other.m_p_nd; return *this; } _CIter& operator=(const PB_DS_CONST_ODIR_IT_C_DEC& other) { m_p_nd = other.m_p_nd; return *this; } const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == leaf_node); return &static_cast(m_p_nd)->value(); } const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == leaf_node); return static_cast(m_p_nd)->value(); } bool operator==(const _CIter& other) const { return m_p_nd == other.m_p_nd; } bool operator==(const PB_DS_CONST_ODIR_IT_C_DEC& other) const { return m_p_nd == other.m_p_nd; } bool operator!=(const _CIter& other) const { return m_p_nd != other.m_p_nd; } bool operator!=(const PB_DS_CONST_ODIR_IT_C_DEC& other) const { return m_p_nd != other.m_p_nd; } _CIter& operator++() { inc(integral_constant()); return *this; } _CIter operator++(int) { _CIter ret_it(m_p_nd); operator++(); return ret_it; } _CIter& operator--() { dec(integral_constant()); return *this; } _CIter operator--(int) { _CIter ret_it(m_p_nd); operator--(); return ret_it; } protected: void inc(false_type) { dec(true_type()); } void inc(true_type) { if (m_p_nd->m_type == head_node) { m_p_nd = static_cast(m_p_nd)->m_p_min; return; } node_pointer p_y = m_p_nd->m_p_parent; while (p_y->m_type != head_node && get_larger_sibling(m_p_nd) == 0) { m_p_nd = p_y; p_y = p_y->m_p_parent; } if (p_y->m_type == head_node) { m_p_nd = p_y; return; } m_p_nd = leftmost_descendant(get_larger_sibling(m_p_nd)); } void dec(false_type) { inc(true_type()); } void dec(true_type) { if (m_p_nd->m_type == head_node) { m_p_nd = static_cast(m_p_nd)->m_p_max; return; } node_pointer p_y = m_p_nd->m_p_parent; while (p_y->m_type != head_node && get_smaller_sibling(m_p_nd) == 0) { m_p_nd = p_y; p_y = p_y->m_p_parent; } if (p_y->m_type == head_node) { m_p_nd = p_y; return; } m_p_nd = rightmost_descendant(get_smaller_sibling(m_p_nd)); } static node_pointer get_larger_sibling(node_pointer p_nd) { inode_pointer p_parent = static_cast(p_nd->m_p_parent); inode_iterator it = p_parent->begin(); while (*it != p_nd) ++it; inode_iterator next_it = it; ++next_it; return (next_it == p_parent->end())? 0 : *next_it; } static node_pointer get_smaller_sibling(node_pointer p_nd) { inode_pointer p_parent = static_cast(p_nd->m_p_parent); inode_iterator it = p_parent->begin(); if (*it == p_nd) return 0; inode_iterator prev_it; do { prev_it = it; ++it; if (*it == p_nd) return *prev_it; } while (true); _GLIBCXX_DEBUG_ASSERT(false); return 0; } static leaf_pointer leftmost_descendant(node_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast(p_nd); return static_cast(p_nd)->leftmost_descendant(); } static leaf_pointer rightmost_descendant(node_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast(p_nd); return static_cast(p_nd)->rightmost_descendant(); } }; /// Iterator. template class _Iter : public _CIter { public: typedef _CIter base_type; typedef typename base_type::allocator_type allocator_type; typedef typename base_type::type_traits type_traits; typedef typename type_traits::value_type value_type; typedef typename type_traits::pointer pointer; typedef typename type_traits::reference reference; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::leaf_pointer leaf_pointer; typedef typename base_type::leaf_const_pointer leaf_const_pointer; typedef typename base_type::head_pointer head_pointer; typedef typename base_type::inode_pointer inode_pointer; _Iter(node_pointer p_nd = 0) : base_type(p_nd) { } _Iter(const PB_DS_ODIR_IT_C_DEC& other) : base_type(other.m_p_nd) { } _Iter& operator=(const _Iter& other) { base_type::m_p_nd = other.m_p_nd; return *this; } _Iter& operator=(const PB_DS_ODIR_IT_C_DEC& other) { base_type::m_p_nd = other.m_p_nd; return *this; } pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == leaf_node); return &static_cast(base_type::m_p_nd)->value(); } reference operator*() const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == leaf_node); return static_cast(base_type::m_p_nd)->value(); } _Iter& operator++() { base_type::operator++(); return *this; } _Iter operator++(int) { _Iter ret(base_type::m_p_nd); operator++(); return ret; } _Iter& operator--() { base_type::operator--(); return *this; } _Iter operator--(int) { _Iter ret(base_type::m_p_nd); operator--(); return ret; } }; #undef PB_DS_CONST_ODIR_IT_C_DEC #undef PB_DS_ODIR_IT_C_DEC #define PB_DS_PAT_TRIE_NODE_CONST_ITERATOR_C_DEC \ _Node_citer #define PB_DS_PAT_TRIE_NODE_ITERATOR_C_DEC \ _Node_iter /// Node const iterator. template class _Node_citer { protected: typedef typename _Alloc::template rebind __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; typedef typename _Alloc::template rebind __rebind_l; typedef typename __rebind_l::other::pointer leaf_pointer; typedef typename __rebind_l::other::const_pointer leaf_const_pointer; typedef typename _Alloc::template rebind __rebind_in; typedef typename __rebind_in::other::pointer inode_pointer; typedef typename __rebind_in::other::const_pointer inode_const_pointer; typedef typename Node::a_const_pointer a_const_pointer; typedef typename Node::a_const_iterator a_const_iterator; private: a_const_iterator pref_begin() const { if (m_p_nd->m_type == leaf_node) { leaf_const_pointer lcp = static_cast(m_p_nd); return m_p_traits->begin(m_p_traits->extract_key(lcp->value())); } _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node); return static_cast(m_p_nd)->pref_b_it(); } a_const_iterator pref_end() const { if (m_p_nd->m_type == leaf_node) { leaf_const_pointer lcp = static_cast(m_p_nd); return m_p_traits->end(m_p_traits->extract_key(lcp->value())); } _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node); return static_cast(m_p_nd)->pref_e_it(); } public: typedef trivial_iterator_tag iterator_category; typedef trivial_iterator_difference_type difference_type; typedef typename _Alloc::size_type size_type; typedef _CIterator value_type; typedef value_type reference; typedef value_type const_reference; /// Metadata type. typedef typename Node::metadata_type metadata_type; /// Const metadata reference type. typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef typename __rebind_ma::const_reference metadata_const_reference; inline _Node_citer(node_pointer p_nd = 0, a_const_pointer p_traits = 0) : m_p_nd(const_cast(p_nd)), m_p_traits(p_traits) { } /// Subtree valid prefix. std::pair valid_prefix() const { return std::make_pair(pref_begin(), pref_end()); } /// Const access; returns the __const iterator* associated with /// the current leaf. const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(num_children() == 0); return _CIterator(m_p_nd); } /// Metadata access. metadata_const_reference get_metadata() const { return m_p_nd->get_metadata(); } /// Returns the number of children in the corresponding node. size_type num_children() const { if (m_p_nd->m_type == leaf_node) return 0; _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node); inode_pointer inp = static_cast(m_p_nd); return std::distance(inp->begin(), inp->end()); } /// Returns a __const node __iterator to the corresponding node's /// i-th child. _Node_citer get_child(size_type i) const { _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node); inode_pointer inp = static_cast(m_p_nd); typename Inode::iterator it = inp->begin(); std::advance(it, i); return _Node_citer(*it, m_p_traits); } /// Compares content to a different iterator object. bool operator==(const _Node_citer& other) const { return m_p_nd == other.m_p_nd; } /// Compares content (negatively) to a different iterator object. bool operator!=(const _Node_citer& other) const { return m_p_nd != other.m_p_nd; } node_pointer m_p_nd; a_const_pointer m_p_traits; }; /// Node iterator. template class _Node_iter : public _Node_citer { private: typedef _Node_citer base_type; typedef typename _Alloc::template rebind __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; typedef typename base_type::inode_pointer inode_pointer; typedef typename base_type::a_const_pointer a_const_pointer; typedef Iterator iterator; public: typedef typename base_type::size_type size_type; typedef Iterator value_type; typedef value_type reference; typedef value_type const_reference; _Node_iter(node_pointer p_nd = 0, a_const_pointer p_traits = 0) : base_type(p_nd, p_traits) { } /// Access; returns the iterator* associated with the current leaf. reference operator*() const { _GLIBCXX_DEBUG_ASSERT(base_type::num_children() == 0); return iterator(base_type::m_p_nd); } /// Returns a node __iterator to the corresponding node's i-th child. _Node_iter get_child(size_type i) const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == i_node); typename Inode::iterator it = static_cast(base_type::m_p_nd)->begin(); std::advance(it, i); return _Node_iter(*it, base_type::m_p_traits); } }; }; #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ pat_trie_base::_Inode<_ATraits, Metadata> PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::__rebind_l PB_DS_CLASS_C_DEC::s_leaf_alloc; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::__rebind_in PB_DS_CLASS_C_DEC::s_inode_alloc; PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_pref_pos(a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) const { if (static_cast(std::distance(b_it, e_it)) <= m_e_ind) return 0; std::advance(b_it, m_e_ind); return 1 + p_traits->e_pos(*b_it); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: _Inode(size_type len, const a_const_iterator it) : base_type(i_node), m_e_ind(len), m_pref_b_it(it), m_pref_e_it(it) { std::advance(m_pref_e_it, m_e_ind); std::fill(m_a_p_children, m_a_p_children + arr_size, static_cast(0)); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: update_prefixes(a_const_pointer p_traits) { node_pointer p_first = *begin(); if (p_first->m_type == leaf_node) { leaf_const_pointer p = static_cast(p_first); m_pref_b_it = p_traits->begin(access_traits::extract_key(p->value())); } else { inode_pointer p = static_cast(p_first); _GLIBCXX_DEBUG_ASSERT(p_first->m_type == i_node); m_pref_b_it = p->pref_b_it(); } m_pref_e_it = m_pref_b_it; std::advance(m_pref_e_it, m_e_ind); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { typedef node_pointer_pointer pointer_type; pointer_type p = const_cast(m_a_p_children); return const_iterator(p + get_begin_pos(), p + arr_size); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { return iterator(m_a_p_children + get_begin_pos(), m_a_p_children + arr_size); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { typedef node_pointer_pointer pointer_type; pointer_type p = const_cast(m_a_p_children) + arr_size; return const_iterator(p, p); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return iterator(m_a_p_children + arr_size, m_a_p_children + arr_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_child_node(a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) { const size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); return m_a_p_children[i]; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: get_child_it(a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) { const size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); _GLIBCXX_DEBUG_ASSERT(m_a_p_children[i] != 0); return iterator(m_a_p_children + i, m_a_p_children + i); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_pointer PB_DS_CLASS_C_DEC:: get_child_node(a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) const { return const_cast(get_child_node(b_it, e_it, p_traits)); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_lower_bound_child_node(a_const_iterator b_it, a_const_iterator e_it, size_type checked_ind, a_const_pointer p_traits) { if (!should_be_mine(b_it, e_it, checked_ind, p_traits)) { if (p_traits->cmp_prefixes(b_it, e_it, m_pref_b_it, m_pref_e_it, true)) return leftmost_descendant(); return rightmost_descendant(); } size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); if (m_a_p_children[i] != 0) return m_a_p_children[i]; while (++i < arr_size) if (m_a_p_children[i] != 0) { const node_type& __nt = m_a_p_children[i]->m_type; node_pointer ret = m_a_p_children[i]; if (__nt == leaf_node) return ret; _GLIBCXX_DEBUG_ASSERT(__nt == i_node); inode_pointer inp = static_cast(ret); return inp->leftmost_descendant(); } return rightmost_descendant(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: add_child(node_pointer p_nd, a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) { const size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); if (m_a_p_children[i] == 0) { m_a_p_children[i] = p_nd; p_nd->m_p_parent = this; return p_nd; } return m_a_p_children[i]; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_const_pointer PB_DS_CLASS_C_DEC:: get_join_child(node_const_pointer p_nd, a_const_pointer p_tr) const { node_pointer p = const_cast(p_nd); return const_cast(this)->get_join_child(p, p_tr); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_join_child(node_pointer p_nd, a_const_pointer p_traits) { size_type i; a_const_iterator b_it; a_const_iterator e_it; if (p_nd->m_type == leaf_node) { leaf_const_pointer p = static_cast(p_nd); typedef typename type_traits::key_const_reference kcr; kcr r_key = access_traits::extract_key(p->value()); b_it = p_traits->begin(r_key); e_it = p_traits->end(r_key); } else { b_it = static_cast(p_nd)->pref_b_it(); e_it = static_cast(p_nd)->pref_e_it(); } i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); return m_a_p_children[i]; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_child(node_pointer p_nd) { size_type i = 0; for (; i < arr_size; ++i) if (m_a_p_children[i] == p_nd) { m_a_p_children[i] = 0; return; } _GLIBCXX_DEBUG_ASSERT(i != arr_size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_child(iterator it) { *it.m_p_p_cur = 0; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: replace_child(node_pointer p_nd, a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) { const size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); m_a_p_children[i] = p_nd; p_nd->m_p_parent = this; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::a_const_iterator PB_DS_CLASS_C_DEC:: pref_b_it() const { return m_pref_b_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::a_const_iterator PB_DS_CLASS_C_DEC:: pref_e_it() const { return m_pref_e_it; } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: should_be_mine(a_const_iterator b_it, a_const_iterator e_it, size_type checked_ind, a_const_pointer p_traits) const { if (m_e_ind == 0) return true; const size_type num_es = std::distance(b_it, e_it); if (num_es < m_e_ind) return false; a_const_iterator key_b_it = b_it; std::advance(key_b_it, checked_ind); a_const_iterator key_e_it = b_it; std::advance(key_e_it, m_e_ind); a_const_iterator value_b_it = m_pref_b_it; std::advance(value_b_it, checked_ind); a_const_iterator value_e_it = m_pref_b_it; std::advance(value_e_it, m_e_ind); return p_traits->equal_prefixes(key_b_it, key_e_it, value_b_it, value_e_it); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: leftmost_descendant() { node_pointer p_pot = *begin(); if (p_pot->m_type == leaf_node) return (static_cast(p_pot)); _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == i_node); return static_cast(p_pot)->leftmost_descendant(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_const_pointer PB_DS_CLASS_C_DEC:: leftmost_descendant() const { return const_cast(this)->leftmost_descendant(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: rightmost_descendant() { const size_type num_children = std::distance(begin(), end()); _GLIBCXX_DEBUG_ASSERT(num_children >= 2); iterator it = begin(); std::advance(it, num_children - 1); node_pointer p_pot =* it; if (p_pot->m_type == leaf_node) return static_cast(p_pot); _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == i_node); return static_cast(p_pot)->rightmost_descendant(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_const_pointer PB_DS_CLASS_C_DEC:: rightmost_descendant() const { return const_cast(this)->rightmost_descendant(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_begin_pos() const { size_type i = 0; for (; i < arr_size && m_a_p_children[i] == 0; ++i) ; return i; } #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_debug_info PB_DS_CLASS_C_DEC:: assert_valid_imp(a_const_pointer p_traits, const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(base_type::m_type == i_node); PB_DS_DEBUG_VERIFY(static_cast(std::distance(pref_b_it(), pref_e_it())) == m_e_ind); PB_DS_DEBUG_VERIFY(std::distance(begin(), end()) >= 2); for (typename _Inode::const_iterator it = begin(); it != end(); ++it) { node_const_pointer p_nd = *it; PB_DS_DEBUG_VERIFY(p_nd->m_p_parent == this); node_debug_info child_ret = p_nd->assert_valid_imp(p_traits, __file, __line); PB_DS_DEBUG_VERIFY(static_cast(std::distance(child_ret.first, child_ret.second)) >= m_e_ind); PB_DS_DEBUG_VERIFY(should_be_mine(child_ret.first, child_ret.second, 0, p_traits)); PB_DS_DEBUG_VERIFY(get_pref_pos(child_ret.first, child_ret.second, p_traits) == static_cast(it.m_p_p_cur - m_a_p_children)); } return std::make_pair(pref_b_it(), pref_e_it()); } #endif #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp000064400000040745152526447520014517 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/pat_trie_.hpp * Contains an implementation class for a patricia tree. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _GLIBCXX_DEBUG #include #endif #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_PAT_TRIE_NAME pat_trie_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_PAT_TRIE_NAME pat_trie_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_PAT_TRIE_NAME #define PB_DS_PAT_TRIE_TRAITS_BASE \ types_traits #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base >, \ typename _Alloc::template rebind::other::const_reference> #endif /** * @brief PATRICIA trie. * @ingroup branch-detail * * This implementation loosely borrows ideas from: * 1) Fast Mergeable Integer Maps, Okasaki, Gill 1998 * 2) Ptset: Sets of integers implemented as Patricia trees, * Jean-Christophe Filliatr, 2000 */ template class PB_DS_PAT_TRIE_NAME : #ifdef _GLIBCXX_DEBUG public PB_DS_DEBUG_MAP_BASE_C_DEC, #endif public Node_And_It_Traits::synth_access_traits, public Node_And_It_Traits::node_update, public PB_DS_PAT_TRIE_TRAITS_BASE, public pat_trie_base { private: typedef pat_trie_base base_type; typedef PB_DS_PAT_TRIE_TRAITS_BASE traits_base; typedef Node_And_It_Traits traits_type; typedef typename traits_type::synth_access_traits synth_access_traits; typedef typename synth_access_traits::const_iterator a_const_iterator; typedef typename traits_type::node node; typedef typename _Alloc::template rebind __rebind_n; typedef typename __rebind_n::other::const_pointer node_const_pointer; typedef typename __rebind_n::other::pointer node_pointer; typedef typename traits_type::head head; typedef typename _Alloc::template rebind __rebind_h; typedef typename __rebind_h::other head_allocator; typedef typename head_allocator::pointer head_pointer; typedef typename traits_type::leaf leaf; typedef typename _Alloc::template rebind __rebind_l; typedef typename __rebind_l::other leaf_allocator; typedef typename leaf_allocator::pointer leaf_pointer; typedef typename leaf_allocator::const_pointer leaf_const_pointer; typedef typename traits_type::inode inode; typedef typename inode::iterator inode_iterator; typedef typename _Alloc::template rebind __rebind_in; typedef typename __rebind_in::other __rebind_ina; typedef typename __rebind_in::other inode_allocator; typedef typename __rebind_ina::pointer inode_pointer; typedef typename __rebind_ina::const_pointer inode_const_pointer; /// Conditional deallocator. class cond_dealtor { protected: leaf_pointer m_p_nd; bool m_no_action_dtor; bool m_call_destructor; public: cond_dealtor(leaf_pointer p_nd) : m_p_nd(p_nd), m_no_action_dtor(false), m_call_destructor(false) { } void set_no_action_dtor() { m_no_action_dtor = true; } void set_call_destructor() { m_call_destructor = true; } ~cond_dealtor() { if (m_no_action_dtor) return; if (m_call_destructor) m_p_nd->~leaf(); s_leaf_allocator.deallocate(m_p_nd, 1); } }; /// Branch bag, for split-join. class branch_bag { private: typedef inode_pointer __inp; typedef typename _Alloc::template rebind<__inp>::other __rebind_inp; #ifdef _GLIBCXX_DEBUG typedef std::_GLIBCXX_STD_C::list<__inp, __rebind_inp> bag_type; #else typedef std::list<__inp, __rebind_inp> bag_type; #endif bag_type m_bag; public: void add_branch() { inode_pointer p_nd = s_inode_allocator.allocate(1); __try { m_bag.push_back(p_nd); } __catch(...) { s_inode_allocator.deallocate(p_nd, 1); __throw_exception_again; } } inode_pointer get_branch() { _GLIBCXX_DEBUG_ASSERT(!m_bag.empty()); inode_pointer p_nd = *m_bag.begin(); m_bag.pop_front(); return p_nd; } ~branch_bag() { while (!m_bag.empty()) { inode_pointer p_nd = *m_bag.begin(); s_inode_allocator.deallocate(p_nd, 1); m_bag.pop_front(); } } inline bool empty() const { return m_bag.empty(); } }; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif typedef typename traits_type::null_node_update_pointer null_node_update_pointer; public: typedef pat_trie_tag container_category; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; typedef typename traits_type::access_traits access_traits; typedef typename traits_type::const_iterator point_const_iterator; typedef typename traits_type::iterator point_iterator; typedef point_const_iterator const_iterator; typedef point_iterator iterator; typedef typename traits_type::reverse_iterator reverse_iterator; typedef typename traits_type::const_reverse_iterator const_reverse_iterator; typedef typename traits_type::node_const_iterator node_const_iterator; typedef typename traits_type::node_iterator node_iterator; typedef typename traits_type::node_update node_update; PB_DS_PAT_TRIE_NAME(); PB_DS_PAT_TRIE_NAME(const access_traits&); PB_DS_PAT_TRIE_NAME(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); ~PB_DS_PAT_TRIE_NAME(); inline bool empty() const; inline size_type size() const; inline size_type max_size() const; access_traits& get_access_traits(); const access_traits& get_access_traits() const; node_update& get_node_update(); const node_update& get_node_update() const; inline std::pair insert(const_reference); inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR return insert(std::make_pair(r_key, mapped_type())).first->second; #else insert(r_key); return traits_base::s_null_type; #endif } inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline point_iterator lower_bound(key_const_reference); inline point_const_iterator lower_bound(key_const_reference) const; inline point_iterator upper_bound(key_const_reference); inline point_const_iterator upper_bound(key_const_reference) const; void clear(); inline bool erase(key_const_reference); inline const_iterator erase(const_iterator); #ifdef PB_DS_DATA_TRUE_INDICATOR inline iterator erase(iterator); #endif inline const_reverse_iterator erase(const_reverse_iterator); #ifdef PB_DS_DATA_TRUE_INDICATOR inline reverse_iterator erase(reverse_iterator); #endif template inline size_type erase_if(Pred); void join(PB_DS_CLASS_C_DEC&); void split(key_const_reference, PB_DS_CLASS_C_DEC&); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; inline reverse_iterator rbegin(); inline const_reverse_iterator rbegin() const; inline reverse_iterator rend(); inline const_reverse_iterator rend() const; /// Returns a const node_iterator corresponding to the node at the /// root of the tree. inline node_const_iterator node_begin() const; /// Returns a node_iterator corresponding to the node at the /// root of the tree. inline node_iterator node_begin(); /// Returns a const node_iterator corresponding to a node just /// after a leaf of the tree. inline node_const_iterator node_end() const; /// Returns a node_iterator corresponding to a node just /// after a leaf of the tree. inline node_iterator node_end(); #ifdef PB_DS_PAT_TRIE_TRACE_ void trace() const; #endif protected: template void copy_from_range(It, It); void value_swap(PB_DS_CLASS_C_DEC&); node_pointer recursive_copy_node(node_const_pointer); private: void initialize(); inline void apply_update(node_pointer, null_node_update_pointer); template inline void apply_update(node_pointer, Node_Update_*); bool join_prep(PB_DS_CLASS_C_DEC&, branch_bag&); void rec_join_prep(node_const_pointer, node_const_pointer, branch_bag&); void rec_join_prep(leaf_const_pointer, leaf_const_pointer, branch_bag&); void rec_join_prep(leaf_const_pointer, inode_const_pointer, branch_bag&); void rec_join_prep(inode_const_pointer, leaf_const_pointer, branch_bag&); void rec_join_prep(inode_const_pointer, inode_const_pointer, branch_bag&); node_pointer rec_join(node_pointer, node_pointer, size_type, branch_bag&); node_pointer rec_join(leaf_pointer, leaf_pointer, branch_bag&); node_pointer rec_join(leaf_pointer, inode_pointer, size_type, branch_bag&); node_pointer rec_join(inode_pointer, leaf_pointer, size_type, branch_bag&); node_pointer rec_join(inode_pointer, inode_pointer, branch_bag&); size_type keys_diff_ind(typename access_traits::const_iterator, typename access_traits::const_iterator, typename access_traits::const_iterator, typename access_traits::const_iterator); inode_pointer insert_branch(node_pointer, node_pointer, branch_bag&); void update_min_max_for_inserted_leaf(leaf_pointer); void erase_leaf(leaf_pointer); inline void actual_erase_leaf(leaf_pointer); void clear_imp(node_pointer); void erase_fixup(inode_pointer); void update_min_max_for_erased_leaf(leaf_pointer); static inline a_const_iterator pref_begin(node_const_pointer); static inline a_const_iterator pref_end(node_const_pointer); inline node_pointer find_imp(key_const_reference); inline node_pointer lower_bound_imp(key_const_reference); inline node_pointer upper_bound_imp(key_const_reference); inline static leaf_const_pointer leftmost_descendant(node_const_pointer); inline static leaf_pointer leftmost_descendant(node_pointer); inline static leaf_const_pointer rightmost_descendant(node_const_pointer); inline static leaf_pointer rightmost_descendant(node_pointer); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void assert_iterators(const char*, int) const; void assert_reverse_iterators(const char*, int) const; static size_type recursive_count_leafs(node_const_pointer, const char*, int); #endif #ifdef PB_DS_PAT_TRIE_TRACE_ static void trace_node(node_const_pointer, size_type); template static void trace_node_metadata(node_const_pointer, type_to_type); static void trace_node_metadata(node_const_pointer, type_to_type); #endif leaf_pointer split_prep(key_const_reference, PB_DS_CLASS_C_DEC&, branch_bag&); node_pointer rec_split(node_pointer, a_const_iterator, a_const_iterator, PB_DS_CLASS_C_DEC&, branch_bag&); void split_insert_branch(size_type, a_const_iterator, inode_iterator, size_type, branch_bag&); static head_allocator s_head_allocator; static inode_allocator s_inode_allocator; static leaf_allocator s_leaf_allocator; head_pointer m_p_head; size_type m_size; }; #define PB_DS_ASSERT_NODE_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X->assert_valid(this, __FILE__, __LINE__);) #define PB_DS_RECURSIVE_COUNT_LEAFS(X) \ recursive_count_leafs(X, __FILE__, __LINE__) #include #include #include #include #include #include #include #include #include #include #include #undef PB_DS_RECURSIVE_COUNT_LEAFS #undef PB_DS_ASSERT_NODE_VALID #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_PAT_TRIE_NAME #undef PB_DS_PAT_TRIE_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC } // namespace detail } // namespace __gnu_pbds 8/ext/pb_ds/detail/pat_trie_/traits.hpp000064400000014241152526447520014047 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/traits.hpp * Contains an implementation class for pat_trie_. */ #ifndef PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP #define PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP #include #include namespace __gnu_pbds { namespace detail { /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct trie_traits { private: typedef pat_trie_base base_type; typedef types_traits type_traits; public: typedef typename trie_node_metadata_dispatch::type metadata_type; typedef base_type::_Metadata metadata; typedef _ATraits access_traits; /// Type for synthesized traits. typedef __gnu_pbds::detail::synth_access_traits synth_access_traits; typedef base_type::_Node_base node; typedef base_type::_Head head; typedef base_type::_Leaf leaf; typedef base_type::_Inode inode; typedef base_type::_Iter iterator; typedef base_type::_CIter const_iterator; typedef base_type::_Iter reverse_iterator; typedef base_type::_CIter const_reverse_iterator; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef base_type::_Node_citer node_const_iterator; typedef base_type::_Node_iter node_iterator; /// Type for node update. typedef Node_Update node_update; typedef null_node_update* null_node_update_pointer; }; /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct trie_traits { private: typedef pat_trie_base base_type; typedef types_traits type_traits; public: typedef typename trie_node_metadata_dispatch::type metadata_type; typedef base_type::_Metadata metadata; typedef _ATraits access_traits; /// Type for synthesized traits. typedef __gnu_pbds::detail::synth_access_traits synth_access_traits; typedef base_type::_Node_base node; typedef base_type::_Head head; typedef base_type::_Leaf leaf; typedef base_type::_Inode inode; typedef base_type::_CIter const_iterator; typedef const_iterator iterator; typedef base_type::_CIter const_reverse_iterator; typedef const_reverse_iterator reverse_iterator; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef base_type::_Node_citer node_const_iterator; typedef node_const_iterator node_iterator; /// Type for node update. typedef Node_Update node_update; typedef null_node_update* null_node_update_pointer; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP 8/ext/pb_ds/detail/trie_policy/order_statistics_imp.hpp000064400000011135152526447520017346 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/order_statistics_imp.hpp * Contains forward declarations for order_statistics_key */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: find_by_order(size_type order) { if (empty()) return end(); ++order; node_iterator nd_it = node_begin(); while (true) { if (order > nd_it.get_metadata()) return ++base_type::rightmost_it(nd_it); const size_type num_children = nd_it.num_children(); if (num_children == 0) return *nd_it; for (size_type i = 0; i < num_children; ++i) { node_iterator child_nd_it = nd_it.get_child(i); if (order <= child_nd_it.get_metadata()) { i = num_children; nd_it = child_nd_it; } else order -= child_nd_it.get_metadata(); } } } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: find_by_order(size_type order) const { return const_cast(this)->find_by_order(order); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: order_of_key(key_const_reference r_key) const { const _ATraits& r_traits = const_cast(this)->get_access_traits(); return order_of_prefix(r_traits.begin(r_key), r_traits.end(r_key)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: order_of_prefix(typename access_traits::const_iterator b, typename access_traits::const_iterator e) const { if (empty()) return 0; const _ATraits& r_traits = const_cast(this)->get_access_traits(); node_const_iterator nd_it = node_begin(); node_const_iterator end_nd_it = node_end(); size_type ord = 0; while (true) { const size_type num_children = nd_it.num_children(); if (num_children == 0) { key_const_reference r_key = base_type::extract_key(*(*nd_it)); typename access_traits::const_iterator key_b = r_traits.begin(r_key); typename access_traits::const_iterator key_e = r_traits.end(r_key); return (base_type::less(key_b, key_e, b, e, r_traits)) ? ord + 1 : ord; } node_const_iterator next_nd_it = end_nd_it; size_type i = num_children - 1; do { node_const_iterator child_nd_it = nd_it.get_child(i); if (next_nd_it != end_nd_it) ord += child_nd_it.get_metadata(); else if (!base_type::less(b, e, child_nd_it.valid_prefix().first, child_nd_it.valid_prefix().second, r_traits)) next_nd_it = child_nd_it; } while (i-- > 0); if (next_nd_it == end_nd_it) return ord; nd_it = next_nd_it; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: operator()(node_iterator nd_it, node_const_iterator /*end_nd_it*/) const { const size_type num_children = nd_it.num_children(); size_type children_rank = 0; for (size_type i = 0; i < num_children; ++i) children_rank += nd_it.get_child(i).get_metadata(); const size_type res = (num_children == 0) ? 1 : children_rank; const_cast(nd_it.get_metadata()) = res; } 8/ext/pb_ds/detail/trie_policy/sample_trie_access_traits.hpp000064400000005231152526447520020327 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/sample_trie_access_traits.hpp * Contains a sample probe policy. */ #ifndef PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP #define PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP namespace __gnu_pbds { /// A sample trie element access traits. struct sample_trie_access_traits { typedef std::size_t size_type; typedef std::string key_type; typedef typename _Alloc::template rebind __rebind_k; typedef typename __rebind_k::other::const_reference key_const_reference; typedef std::string::const_iterator const_iterator; /// Element type. typedef char e_type; enum { max_size = 4 }; /// Returns a const_iterator to the first element of r_key. inline static const_iterator begin(key_const_reference); /// Returns a const_iterator to the after-last element of r_key. inline static const_iterator end(key_const_reference); /// Maps an element to a position. inline static size_type e_pos(e_type); }; } #endif // #ifndef PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP 8/ext/pb_ds/detail/trie_policy/node_metadata_selector.hpp000064400000006412152526447520017603 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/node_metadata_selector.hpp * Contains an implementation class for tries. */ #ifndef PB_DS_TRIE_NODE_METADATA_DISPATCH_HPP #define PB_DS_TRIE_NODE_METADATA_DISPATCH_HPP #include #include namespace __gnu_pbds { namespace detail { /** * @addtogroup traits Traits * @{ */ /// Trie metadata helper. template struct trie_metadata_helper; /// Specialization, false. template struct trie_metadata_helper { typedef typename Node_Update::metadata_type type; }; /// Specialization, true. template struct trie_metadata_helper { typedef null_type type; }; /// Trie node metadata dispatch. template class Node_Update, typename _Alloc> struct trie_node_metadata_dispatch { private: typedef dumnode_const_iterator __it_type; typedef Node_Update<__it_type, __it_type, Cmp_Fn, _Alloc> __node_u; typedef null_node_update<__it_type, __it_type, Cmp_Fn, _Alloc> __nnode_u; enum { null_update = is_same<__node_u, __nnode_u>::value }; public: typedef typename trie_metadata_helper<__node_u, null_update>::type type; }; //@} } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_TRIE_NODE_METADATA_DISPATCH_HPP 8/ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hpp000064400000010637152526447520021160 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/prefix_search_node_update_imp.hpp * Contains an implementation of prefix_search_node_update. */ PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::const_iterator, typename PB_DS_CLASS_C_DEC::const_iterator> PB_DS_CLASS_C_DEC:: prefix_range(key_const_reference r_key) const { const access_traits& r_traits = get_access_traits(); return (prefix_range(r_traits.begin(r_key), r_traits.end(r_key))); } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::iterator, typename PB_DS_CLASS_C_DEC::iterator> PB_DS_CLASS_C_DEC:: prefix_range(key_const_reference r_key) { return (prefix_range(get_access_traits().begin(r_key), get_access_traits().end(r_key))); } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::const_iterator, typename PB_DS_CLASS_C_DEC::const_iterator> PB_DS_CLASS_C_DEC:: prefix_range(typename access_traits::const_iterator b, typename access_traits::const_iterator e) const { const std::pair non_const_ret = const_cast(this)->prefix_range(b, e); return (std::make_pair(const_iterator(non_const_ret.first), const_iterator(non_const_ret.second))); } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::iterator, typename PB_DS_CLASS_C_DEC::iterator> PB_DS_CLASS_C_DEC:: prefix_range(typename access_traits::const_iterator b, typename access_traits::const_iterator e) { Node_Itr nd_it = node_begin(); Node_Itr end_nd_it = node_end(); const access_traits& r_traits = get_access_traits(); const size_type given_range_length = std::distance(b, e); while (true) { if (nd_it == end_nd_it) return (std::make_pair(end(), end())); const size_type common_range_length = base_type::common_prefix_len(nd_it, b, e, r_traits); if (common_range_length >= given_range_length) { iterator ret_b = this->leftmost_it(nd_it); iterator ret_e = this->rightmost_it(nd_it); return (std::make_pair(ret_b, ++ret_e)); } nd_it = next_child(nd_it, b, e, end_nd_it, r_traits); } } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: next_child(node_iterator nd_it, typename access_traits::const_iterator b, typename access_traits::const_iterator e, node_iterator end_nd_it, const access_traits& r_traits) { const size_type num_children = nd_it.num_children(); node_iterator ret = end_nd_it; size_type max_length = 0; for (size_type i = 0; i < num_children; ++i) { node_iterator pot = nd_it.get_child(i); const size_type common_range_length = base_type::common_prefix_len(pot, b, e, r_traits); if (common_range_length > max_length) { ret = pot; max_length = common_range_length; } } return (ret); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: operator()(node_iterator /*nd_it*/, node_const_iterator /*end_nd_it*/) const { } 8/ext/pb_ds/detail/trie_policy/trie_string_access_traits_imp.hpp000064400000005753152526447520021232 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/trie_string_access_traits_imp.hpp * Contains a policy for extracting character positions from * a string for a vector-based PATRICIA tree */ PB_DS_CLASS_T_DEC detail::integral_constant PB_DS_CLASS_C_DEC::s_rev_ind; PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: e_pos(e_type e) { return (static_cast(e - min_e_val)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin(key_const_reference r_key) { return (begin_imp(r_key, s_rev_ind)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end(key_const_reference r_key) { return (end_imp(r_key, s_rev_ind)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin_imp(key_const_reference r_key, detail::false_type) { return (r_key.begin()); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin_imp(key_const_reference r_key, detail::true_type) { return (r_key.rbegin()); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end_imp(key_const_reference r_key, detail::false_type) { return (r_key.end()); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end_imp(key_const_reference r_key, detail::true_type) { return (r_key.rend()); } 8/ext/pb_ds/detail/trie_policy/sample_trie_node_update.hpp000064400000004454152526447520017775 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/sample_trie_node_update.hpp * Contains a samle node update functor. */ #ifndef PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP #define PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP namespace __gnu_pbds { /// A sample node updator. template class sample_trie_node_update { public: typedef std::size_t metadata_type; protected: /// Default constructor. sample_trie_node_update(); /// Updates the rank of a node through a node_iterator node_it; /// end_nd_it is the end node iterator. inline void operator()(node_iterator, node_const_iterator) const; }; } #endif // #ifndef PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP 8/ext/pb_ds/detail/trie_policy/trie_policy_base.hpp000064400000013327152526447520016435 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/trie_policy_base.hpp * Contains an implementation of trie_policy_base. */ #ifndef PB_DS_TRIE_POLICY_BASE_HPP #define PB_DS_TRIE_POLICY_BASE_HPP #include namespace __gnu_pbds { namespace detail { /// Base class for trie policies. template class trie_policy_base : public branch_policy { typedef branch_policy base_type; public: typedef _ATraits access_traits; typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef null_type metadata_type; typedef Node_CItr node_const_iterator; typedef Node_Itr node_iterator; typedef typename node_const_iterator::value_type const_iterator; typedef typename node_iterator::value_type iterator; typedef typename base_type::key_type key_type; typedef typename base_type::key_const_reference key_const_reference; protected: virtual const_iterator end() const = 0; virtual iterator end() = 0; virtual node_const_iterator node_begin() const = 0; virtual node_iterator node_begin() = 0; virtual node_const_iterator node_end() const = 0; virtual node_iterator node_end() = 0; virtual const access_traits& get_access_traits() const = 0; private: typedef typename access_traits::const_iterator e_const_iterator; typedef std::pair prefix_range_t; protected: static size_type common_prefix_len(node_iterator, e_const_iterator, e_const_iterator, const access_traits&); static iterator leftmost_it(node_iterator); static iterator rightmost_it(node_iterator); static bool less(e_const_iterator, e_const_iterator, e_const_iterator, e_const_iterator, const access_traits&); }; #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ trie_policy_base PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: common_prefix_len(node_iterator nd_it, e_const_iterator b_r, e_const_iterator e_r, const access_traits& r_traits) { prefix_range_t pref_range = nd_it.valid_prefix(); e_const_iterator b_l = pref_range.first; e_const_iterator e_l = pref_range.second; const size_type range_length_l = std::distance(b_l, e_l); const size_type range_length_r = std::distance(b_r, e_r); if (range_length_r < range_length_l) { std::swap(b_l, b_r); std::swap(e_l, e_r); } size_type ret = 0; while (b_l != e_l) { if (r_traits.e_pos(*b_l) != r_traits.e_pos(*b_r)) return ret; ++ret; ++b_l; ++b_r; } return ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: leftmost_it(node_iterator nd_it) { if (nd_it.num_children() == 0) return *nd_it; return leftmost_it(nd_it.get_child(0)); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: rightmost_it(node_iterator nd_it) { const size_type num_children = nd_it.num_children(); if (num_children == 0) return *nd_it; return rightmost_it(nd_it.get_child(num_children - 1)); } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: less(e_const_iterator b_l, e_const_iterator e_l, e_const_iterator b_r, e_const_iterator e_r, const access_traits& r_traits) { while (b_l != e_l) { if (b_r == e_r) return false; size_type l_pos = r_traits.e_pos(*b_l); size_type r_pos = r_traits.e_pos(*b_r); if (l_pos != r_pos) return (l_pos < r_pos); ++b_l; ++b_r; } return b_r != e_r; } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_TRIE_POLICY_BASE_HPP 8/ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp000064400000003652152526447520015506 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/trace_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ #ifdef PB_DS_THIN_HEAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << std::endl; std::cerr << "m_p_max " << m_p_max << std::endl; base_type::trace(); } #endif // #ifdef PB_DS_THIN_HEAP_TRACE_ 8/ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp000064400000005602152526447520021433 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) push(*(first_it++)); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: thin_heap() : m_p_max(0) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: thin_heap(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn), m_p_max(0) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: thin_heap(const PB_DS_CLASS_C_DEC& other) : base_type(other) { initialize(); m_p_max = base_type::m_p_root; for (node_pointer p_nd = base_type::m_p_root; p_nd != 0; p_nd = p_nd->m_p_next_sibling) if (Cmp_Fn::operator()(m_p_max->m_value, p_nd->m_value)) m_p_max = p_nd; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) base_type::swap(other); std::swap(m_p_max, other.m_p_max); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~thin_heap() { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { std::fill(m_a_aux, m_a_aux + max_rank, static_cast(0)); } 8/ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp000064400000003640152526447520015325 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/find_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top() const { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); _GLIBCXX_DEBUG_ASSERT(m_p_max != 0); return m_p_max->m_value; } 8/ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp000064400000007432152526447520015476 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/debug_fn_imps.hpp * Contains an implementation for thin_heap_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(__file, __line); assert_node_consistent(base_type::m_p_root, true, __file, __line); assert_max(__file, __line); assert_aux_null(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_aux_null(const char* __file, int __line) const { for (size_type i = 0; i < max_rank; ++i) PB_DS_DEBUG_VERIFY(m_a_aux[i] == 0); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_max(const char* __file, int __line) const { if (m_p_max == 0) { PB_DS_DEBUG_VERIFY(base_type::empty()); return; } PB_DS_DEBUG_VERIFY(!base_type::empty()); PB_DS_DEBUG_VERIFY(base_type::parent(m_p_max) == 0); PB_DS_DEBUG_VERIFY(m_p_max->m_p_prev_or_parent == 0); for (const_iterator it = base_type::begin(); it != base_type::end(); ++it) PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(m_p_max->m_value, it.m_p_nd->m_value)); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent(node_const_pointer p_nd, bool root, const char* __file, int __line) const { base_type::assert_node_consistent(p_nd, root, __file, __line); if (p_nd == 0) return; assert_node_consistent(p_nd->m_p_next_sibling, root, __file, __line); assert_node_consistent(p_nd->m_p_l_child, false, __file, __line); if (!root) { if (p_nd->m_metadata == 0) PB_DS_DEBUG_VERIFY(p_nd->m_p_next_sibling == 0); else PB_DS_DEBUG_VERIFY(p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata + 1); } if (p_nd->m_p_l_child != 0) PB_DS_DEBUG_VERIFY(p_nd->m_p_l_child->m_metadata + 1 == base_type::degree(p_nd)); const bool unmarked_valid = (p_nd->m_p_l_child == 0 && p_nd->m_metadata == 0) || (p_nd->m_p_l_child != 0 && p_nd->m_metadata == p_nd->m_p_l_child->m_metadata + 1); const bool marked_valid = (p_nd->m_p_l_child == 0 && p_nd->m_metadata == 1) || (p_nd->m_p_l_child != 0 && p_nd->m_metadata == p_nd->m_p_l_child->m_metadata + 2); PB_DS_DEBUG_VERIFY(unmarked_valid || marked_valid); if (root) PB_DS_DEBUG_VERIFY(unmarked_valid); } #endif 8/ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp000064400000016473152526447520015721 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/insert_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = base_type::get_new_node_for_insert(r_val); p_nd->m_metadata = 0; p_nd->m_p_prev_or_parent = p_nd->m_p_l_child = 0; if (base_type::m_p_root == 0) { p_nd->m_p_next_sibling = 0; m_p_max = base_type::m_p_root = p_nd; PB_DS_ASSERT_VALID((*this)) return point_iterator(p_nd); } p_nd->m_p_next_sibling = base_type::m_p_root; base_type::m_p_root->m_p_prev_or_parent = 0; base_type::m_p_root = p_nd; update_max(p_nd); PB_DS_ASSERT_VALID((*this)) return point_iterator(p_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_root(node_pointer p_nd) { p_nd->m_metadata = p_nd->m_p_l_child == 0 ? 0 : 1 + p_nd->m_p_l_child->m_metadata; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_root_and_link(node_pointer p_nd) { make_root(p_nd); p_nd->m_p_prev_or_parent = 0; p_nd->m_p_next_sibling = base_type::m_p_root; if (base_type::m_p_root != 0) base_type::m_p_root->m_p_prev_or_parent = 0; base_type::m_p_root = p_nd; update_max(p_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix(node_pointer p_y) { while (true) { if (p_y->m_p_prev_or_parent == 0) { fix_root(p_y); return; } else if (p_y->m_metadata == 1&& p_y->m_p_next_sibling == 0) { if (p_y->m_p_l_child != 0) { fix_sibling_rank_1_unmarked(p_y); return; } fix_sibling_rank_1_marked(p_y); p_y = p_y->m_p_prev_or_parent; } else if (p_y->m_metadata > p_y->m_p_next_sibling->m_metadata + 1) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_l_child != 0); if (p_y->m_metadata != p_y->m_p_l_child->m_metadata + 2) { fix_sibling_general_unmarked(p_y); return; } fix_sibling_general_marked(p_y); p_y = p_y->m_p_prev_or_parent; } else if ((p_y->m_p_l_child == 0&& p_y->m_metadata == 2) ||(p_y->m_p_l_child != 0&& p_y->m_metadata == p_y->m_p_l_child->m_metadata + 3)) { node_pointer p_z = p_y->m_p_prev_or_parent; fix_child(p_y); p_y = p_z; } else return; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_root(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent == 0); make_root(p_y); PB_DS_ASSERT_NODE_CONSISTENT(p_y, true) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_sibling_rank_1_unmarked(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); _GLIBCXX_DEBUG_ONLY(node_pointer p_w = p_y->m_p_l_child;) _GLIBCXX_DEBUG_ASSERT(p_w != 0); _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling == 0); _GLIBCXX_DEBUG_ASSERT(p_y->m_p_next_sibling == 0); p_y->m_p_next_sibling = p_y->m_p_l_child; p_y->m_p_next_sibling->m_p_prev_or_parent = p_y; p_y->m_p_l_child = 0; PB_DS_ASSERT_NODE_CONSISTENT(p_y, false) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_sibling_rank_1_marked(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); _GLIBCXX_DEBUG_ASSERT(p_y->m_p_l_child == 0); p_y->m_metadata = 0; PB_DS_ASSERT_NODE_CONSISTENT(p_y, false) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_sibling_general_unmarked(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); node_pointer p_w = p_y->m_p_l_child; _GLIBCXX_DEBUG_ASSERT(p_w != 0); _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling != 0); p_y->m_p_l_child = p_w->m_p_next_sibling; p_w->m_p_next_sibling->m_p_prev_or_parent = p_y; p_w->m_p_next_sibling = p_y->m_p_next_sibling; _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling != 0); p_w->m_p_next_sibling->m_p_prev_or_parent = p_w; p_y->m_p_next_sibling = p_w; p_w->m_p_prev_or_parent = p_y; PB_DS_ASSERT_NODE_CONSISTENT(p_y, false) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_sibling_general_marked(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); --p_y->m_metadata; PB_DS_ASSERT_NODE_CONSISTENT(p_y, false) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_child(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); if (p_y->m_p_next_sibling != 0) p_y->m_p_next_sibling->m_p_prev_or_parent = p_y->m_p_prev_or_parent; if (p_y->m_p_prev_or_parent->m_p_l_child == p_y) p_y->m_p_prev_or_parent->m_p_l_child = p_y->m_p_next_sibling; else p_y->m_p_prev_or_parent->m_p_next_sibling = p_y->m_p_next_sibling; make_root_and_link(p_y); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = it.m_p_nd; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); const bool smaller = Cmp_Fn::operator()(r_new_val, p_nd->m_value); p_nd->m_value = r_new_val; if (smaller) { remove_node(p_nd); p_nd->m_p_l_child = 0; make_root_and_link(p_nd); PB_DS_ASSERT_VALID((*this)) return; } if (p_nd->m_p_prev_or_parent == 0) { update_max(p_nd); PB_DS_ASSERT_VALID((*this)) return; } node_pointer p_y = p_nd->m_p_prev_or_parent; _GLIBCXX_DEBUG_ASSERT(p_y != 0); if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_y; if (p_y->m_p_l_child == p_nd) p_y->m_p_l_child = p_nd->m_p_next_sibling; else p_y->m_p_next_sibling = p_nd->m_p_next_sibling; fix(p_y); make_root_and_link(p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_max(node_pointer p_nd) { if (m_p_max == 0 || Cmp_Fn::operator()(m_p_max->m_value, p_nd->m_value)) m_p_max = p_nd; } 8/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp000064400000020324152526447520014766 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/thin_heap_.hpp * Contains an implementation class for a thin heap. */ #ifndef PB_DS_THIN_HEAP_HPP #define PB_DS_THIN_HEAP_HPP #include #include #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ thin_heap #ifdef _GLIBCXX_DEBUG #define PB_DS_BASE_T_P \ #else #define PB_DS_BASE_T_P \ #endif /** * Thin heap. * * @ingroup heap-detail * * See Tarjan and Kaplan. */ template class thin_heap : public left_child_next_sibling_heap PB_DS_BASE_T_P { private: typedef typename _Alloc::template rebind::other __rebind_a; typedef left_child_next_sibling_heap PB_DS_BASE_T_P base_type; protected: typedef typename base_type::node node; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::node_const_pointer node_const_pointer; public: typedef Value_Type value_type; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename __rebind_a::pointer pointer; typedef typename __rebind_a::const_pointer const_pointer; typedef typename __rebind_a::reference reference; typedef typename __rebind_a::const_reference const_reference; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline const_reference top() const; void pop(); void erase(point_iterator); inline void clear(); template size_type erase_if(Pred); template void split(Pred, PB_DS_CLASS_C_DEC&); void join(PB_DS_CLASS_C_DEC&); protected: thin_heap(); thin_heap(const Cmp_Fn&); thin_heap(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); ~thin_heap(); template void copy_from_range(It, It); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void assert_max(const char*, int) const; #endif #ifdef PB_DS_THIN_HEAP_TRACE_ void trace() const; #endif private: enum { max_rank = (sizeof(size_type) << 4) + 2 }; void initialize(); inline void update_max(node_pointer); inline void fix(node_pointer); inline void fix_root(node_pointer); inline void fix_sibling_rank_1_unmarked(node_pointer); inline void fix_sibling_rank_1_marked(node_pointer); inline void fix_sibling_general_unmarked(node_pointer); inline void fix_sibling_general_marked(node_pointer); inline void fix_child(node_pointer); inline static void make_root(node_pointer); inline void make_root_and_link(node_pointer); inline void remove_max_node(); void to_aux_except_max(); inline void add_to_aux(node_pointer); inline void make_from_aux(); inline size_type rank_bound(); inline void make_child_of(node_pointer, node_pointer); inline void remove_node(node_pointer); inline node_pointer join(node_pointer, node_pointer) const; #ifdef _GLIBCXX_DEBUG void assert_node_consistent(node_const_pointer, bool, const char*, int) const; void assert_aux_null(const char*, int) const; #endif node_pointer m_p_max; node_pointer m_a_aux[max_rank]; }; enum { num_distinct_rank_bounds = 48 }; // Taken from the SGI implementation; acknowledged in the docs. static const std::size_t g_a_rank_bounds[num_distinct_rank_bounds] = { /* Dealing cards... */ /* 0 */ 0ul, /* 1 */ 1ul, /* 2 */ 1ul, /* 3 */ 2ul, /* 4 */ 4ul, /* 5 */ 6ul, /* 6 */ 11ul, /* 7 */ 17ul, /* 8 */ 29ul, /* 9 */ 46ul, /* 10 */ 76ul, /* 11 */ 122ul, /* 12 */ 199ul, /* 13 */ 321ul, /* 14 */ 521ul, /* 15 */ 842ul, /* 16 */ 1364ul, /* 17 */ 2206ul, /* 18 */ 3571ul, /* 19 */ 5777ul, /* 20 */ 9349ul, /* 21 */ 15126ul, /* 22 */ 24476ul, /* 23 */ 39602ul, /* 24 */ 64079ul #if __SIZE_MAX__ > 0xfffful , /* 25 */ 103681ul, /* 26 */ 167761ul, /* 27 */ 271442ul, /* 28 */ 439204ul, /* 29 */ 710646ul #if __SIZE_MAX__ > 0xffffful , /* 30 */ 1149851ul, /* 31 */ 1860497ul, /* 32 */ 3010349ul, /* 33 */ 4870846ul, /* 34 */ 7881196ul, /* 35 */ 12752042ul #if __SIZE_MAX__ > 0xfffffful , /* 36 */ 20633239ul, /* 37 */ 33385282ul, /* 38 */ 54018521ul, /* 39 */ 87403803ul, /* 40 */ 141422324ul, /* 41 */ 228826127ul, /* 42 */ 370248451ul, /* 43 */ 599074578ul, /* 44 */ 969323029ul, /* 45 */ 1568397607ul, /* 46 */ 2537720636ul, /* 47 */ 4106118243ul #endif #endif #endif /* Pot's good, let's play */ }; #define PB_DS_ASSERT_NODE_CONSISTENT(_Node, _Bool) \ _GLIBCXX_DEBUG_ONLY(assert_node_consistent(_Node, _Bool, \ __FILE__, __LINE__);) #define PB_DS_ASSERT_AUX_NULL(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_aux_null(__FILE__, __LINE__);) #include #include #include #include #include #include #include #undef PB_DS_ASSERT_AUX_NULL #undef PB_DS_ASSERT_NODE_CONSISTENT #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_BASE_T_P } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp000064400000013647152526447520015514 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/erase_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: pop() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); _GLIBCXX_DEBUG_ASSERT(m_p_max != 0); node_pointer p_nd = m_p_max; remove_max_node(); base_type::actual_erase_node(p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: remove_max_node() { to_aux_except_max(); make_from_aux(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: to_aux_except_max() { node_pointer p_add = base_type::m_p_root; while (p_add != m_p_max) { node_pointer p_next_add = p_add->m_p_next_sibling; add_to_aux(p_add); p_add = p_next_add; } p_add = m_p_max->m_p_l_child; while (p_add != 0) { node_pointer p_next_add = p_add->m_p_next_sibling; p_add->m_metadata = p_add->m_p_l_child == 0 ? 0 : p_add->m_p_l_child->m_metadata + 1; add_to_aux(p_add); p_add = p_next_add; } p_add = m_p_max->m_p_next_sibling; while (p_add != 0) { node_pointer p_next_add = p_add->m_p_next_sibling; add_to_aux(p_add); p_add = p_next_add; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: add_to_aux(node_pointer p_nd) { size_type r = p_nd->m_metadata; while (m_a_aux[r] != 0) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound()); if (Cmp_Fn::operator()(m_a_aux[r]->m_value, p_nd->m_value)) make_child_of(m_a_aux[r], p_nd); else { make_child_of(p_nd, m_a_aux[r]); p_nd = m_a_aux[r]; } m_a_aux[r] = 0; ++r; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound()); m_a_aux[r] = p_nd; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_child_of(node_pointer p_nd, node_pointer p_new_parent) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_new_parent->m_metadata); _GLIBCXX_DEBUG_ASSERT(m_a_aux[p_nd->m_metadata] == p_nd || m_a_aux[p_nd->m_metadata] == p_new_parent); ++p_new_parent->m_metadata; base_type::make_child_of(p_nd, p_new_parent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_from_aux() { base_type::m_p_root = m_p_max = 0; const size_type rnk_bnd = rank_bound(); size_type i = 0; while (i < rnk_bnd) { if (m_a_aux[i] != 0) { make_root_and_link(m_a_aux[i]); m_a_aux[i] = 0; } ++i; } PB_DS_ASSERT_AUX_NULL((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: remove_node(node_pointer p_nd) { node_pointer p_parent = p_nd; while (base_type::parent(p_parent) != 0) p_parent = base_type::parent(p_parent); base_type::bubble_to_top(p_nd); m_p_max = p_nd; node_pointer p_fix = base_type::m_p_root; while (p_fix != 0&& p_fix->m_p_next_sibling != p_parent) p_fix = p_fix->m_p_next_sibling; if (p_fix != 0) p_fix->m_p_next_sibling = p_nd; remove_max_node(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: clear() { base_type::clear(); m_p_max = 0; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); node_pointer p_nd = it.m_p_nd; remove_node(p_nd); base_type::actual_erase_node(p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) if (base_type::empty()) { PB_DS_ASSERT_VALID((*this)) return 0; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); size_type ersd = 0; while (p_out != 0) { ++ersd; node_pointer p_next = p_out->m_p_next_sibling; base_type::actual_erase_node(p_out); p_out = p_next; } node_pointer p_cur = base_type::m_p_root; m_p_max = base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; make_root_and_link(p_cur); p_cur = p_next; } PB_DS_ASSERT_VALID((*this)) return ersd; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: rank_bound() { using namespace std; const size_t* const p_upper = std::upper_bound(g_a_rank_bounds, g_a_rank_bounds + num_distinct_rank_bounds, base_type::m_size); if (p_upper == g_a_rank_bounds + num_distinct_rank_bounds) return max_rank; return (p_upper - g_a_rank_bounds); } 8/ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp000064400000006123152526447520016556 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/split_join_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) other.clear(); if (base_type::empty()) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); while (p_out != 0) { _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); --base_type::m_size; ++other.m_size; node_pointer p_next = p_out->m_p_next_sibling; other.make_root_and_link(p_out); p_out = p_next; } PB_DS_ASSERT_VALID(other) node_pointer p_cur = base_type::m_p_root; m_p_max = 0; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; make_root_and_link(p_cur); p_cur = p_next; } PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) node_pointer p_other = other.m_p_root; while (p_other != 0) { node_pointer p_next = p_other->m_p_next_sibling; make_root_and_link(p_other); p_other = p_next; } base_type::m_size += other.m_size; other.m_p_root = 0; other.m_size = 0; other.m_p_max = 0; PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } 8/ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp000064400000014072152526447520020435 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/binomial_heap_base_.hpp * Contains an implementation class for a base of binomial heaps. */ #ifndef PB_DS_BINOMIAL_HEAP_BASE_HPP #define PB_DS_BINOMIAL_HEAP_BASE_HPP /* * Binomial heap base. * Vuillemin J is the mastah. * Modified from CLRS. */ #include #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ binomial_heap_base #ifdef _GLIBCXX_DEBUG #define PB_DS_B_HEAP_BASE \ left_child_next_sibling_heap #else #define PB_DS_B_HEAP_BASE \ left_child_next_sibling_heap #endif /// Base class for binomial heap. template class binomial_heap_base : public PB_DS_B_HEAP_BASE { private: typedef typename _Alloc::template rebind::other __rebind_v; typedef PB_DS_B_HEAP_BASE base_type; protected: typedef typename base_type::node node; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::node_const_pointer node_const_pointer; public: typedef Value_Type value_type; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename __rebind_v::pointer pointer; typedef typename __rebind_v::const_pointer const_pointer; typedef typename __rebind_v::reference reference; typedef typename __rebind_v::const_reference const_reference; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator iterator; public: inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline const_reference top() const; void pop(); void erase(point_iterator); inline void clear(); template size_type erase_if(Pred); template void split(Pred, PB_DS_CLASS_C_DEC&); void join(PB_DS_CLASS_C_DEC&); protected: binomial_heap_base(); binomial_heap_base(const Cmp_Fn&); binomial_heap_base(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); ~binomial_heap_base(); template void copy_from_range(It, It); inline void find_max(); #ifdef _GLIBCXX_DEBUG void assert_valid(bool, const char*, int) const; void assert_max(const char*, int) const; #endif private: inline node_pointer fix(node_pointer) const; inline void insert_node(node_pointer); inline void remove_parentless_node(node_pointer); inline node_pointer join(node_pointer, node_pointer) const; #ifdef _GLIBCXX_DEBUG void assert_node_consistent(node_const_pointer, bool, bool, const char*, int) const; #endif protected: node_pointer m_p_max; }; #define PB_DS_ASSERT_VALID_COND(X, _StrictlyBinomial) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(_StrictlyBinomial,__FILE__, __LINE__);) #define PB_DS_ASSERT_BASE_NODE_CONSISTENT(_Node, _Bool) \ _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(_Node, _Bool, \ __FILE__, __LINE__);) #include #include #include #include #include #include #undef PB_DS_ASSERT_BASE_NODE_CONSISTENT #undef PB_DS_ASSERT_VALID_COND #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_B_HEAP_BASE } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp000064400000005200152526447520023247 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/constructors_destructor_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) push(*(first_it++)); PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap_base() : m_p_max(0) { PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap_base(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn), m_p_max(0) { PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap_base(const PB_DS_CLASS_C_DEC& other) : base_type(other), m_p_max(0) { PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID_COND((*this),false) base_type::swap(other); std::swap(m_p_max, other.m_p_max); PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~binomial_heap_base() { } 8/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp000064400000004451152526447520017150 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/find_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top() const { PB_DS_ASSERT_VALID_COND((*this),false) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); if (m_p_max == 0) const_cast(this)->find_max(); _GLIBCXX_DEBUG_ASSERT(m_p_max != 0); return m_p_max->m_value; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: find_max() { node_pointer p_cur = base_type::m_p_root; m_p_max = p_cur; while (p_cur != 0) { if (Cmp_Fn::operator()(m_p_max->m_value, p_cur->m_value)) m_p_max = p_cur; p_cur = p_cur->m_p_next_sibling; } } 8/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp000064400000006614152526447520017321 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/debug_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(bool strictly_binomial, const char* __file, int __line) const { base_type::assert_valid(__file, __line); assert_node_consistent(base_type::m_p_root, strictly_binomial, true, __file, __line); assert_max(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_max(const char* __file, int __line) const { if (m_p_max == 0) return; PB_DS_DEBUG_VERIFY(base_type::parent(m_p_max) == 0); for (const_iterator it = base_type::begin(); it != base_type::end(); ++it) PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(m_p_max->m_value, it.m_p_nd->m_value)); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent(node_const_pointer p_nd, bool strictly_binomial, bool increasing, const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(increasing || strictly_binomial); base_type::assert_node_consistent(p_nd, false, __file, __line); if (p_nd == 0) return; PB_DS_DEBUG_VERIFY(p_nd->m_metadata == base_type::degree(p_nd)); PB_DS_DEBUG_VERIFY(base_type::size_under_node(p_nd) == static_cast(1 << p_nd->m_metadata)); assert_node_consistent(p_nd->m_p_next_sibling, strictly_binomial, increasing, __file, __line); assert_node_consistent(p_nd->m_p_l_child, true, false, __file, __line); if (p_nd->m_p_next_sibling != 0) { if (increasing) { if (strictly_binomial) PB_DS_DEBUG_VERIFY(p_nd->m_metadata < p_nd->m_p_next_sibling->m_metadata); else PB_DS_DEBUG_VERIFY(p_nd->m_metadata <= p_nd->m_p_next_sibling->m_metadata); } else PB_DS_DEBUG_VERIFY(p_nd->m_metadata > p_nd->m_p_next_sibling->m_metadata); } } #endif 8/ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp000064400000012227152526447520017534 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/insert_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID_COND((*this),true) node_pointer p_nd = base_type::get_new_node_for_insert(r_val); insert_node(p_nd); m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) return point_iterator(p_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_node(node_pointer p_nd) { if (base_type::m_p_root == 0) { p_nd->m_p_next_sibling = 0; p_nd->m_p_prev_or_parent = 0; p_nd->m_p_l_child = 0; p_nd->m_metadata = 0; base_type::m_p_root = p_nd; return; } if (base_type::m_p_root->m_metadata > 0) { p_nd->m_p_prev_or_parent = p_nd->m_p_l_child = 0; p_nd->m_p_next_sibling = base_type::m_p_root; base_type::m_p_root->m_p_prev_or_parent = p_nd; base_type::m_p_root = p_nd; p_nd->m_metadata = 0; return; } if (Cmp_Fn::operator()(base_type::m_p_root->m_value, p_nd->m_value)) { p_nd->m_p_next_sibling = base_type::m_p_root->m_p_next_sibling; p_nd->m_p_prev_or_parent = 0; p_nd->m_metadata = 1; p_nd->m_p_l_child = base_type::m_p_root; base_type::m_p_root->m_p_prev_or_parent = p_nd; base_type::m_p_root->m_p_next_sibling = 0; base_type::m_p_root = p_nd; } else { p_nd->m_p_next_sibling = 0; p_nd->m_p_l_child = 0; p_nd->m_p_prev_or_parent = base_type::m_p_root; p_nd->m_metadata = 0; _GLIBCXX_DEBUG_ASSERT(base_type::m_p_root->m_p_l_child == 0); base_type::m_p_root->m_p_l_child = p_nd; base_type::m_p_root->m_metadata = 1; } base_type::m_p_root = fix(base_type::m_p_root); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: fix(node_pointer p_nd) const { while (p_nd->m_p_next_sibling != 0 && p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata) { node_pointer p_next = p_nd->m_p_next_sibling; if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) { p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; if (p_nd->m_p_prev_or_parent != 0) p_nd->m_p_prev_or_parent->m_p_next_sibling = p_next; base_type::make_child_of(p_nd, p_next); ++p_next->m_metadata; p_nd = p_next; } else { p_nd->m_p_next_sibling = p_next->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_next->m_p_next_sibling = 0; base_type::make_child_of(p_next, p_nd); ++p_nd->m_metadata; } } if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; return p_nd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID_COND((*this),true) node_pointer p_nd = it.m_p_nd; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_nd, false) const bool bubble_up = Cmp_Fn::operator()(p_nd->m_value, r_new_val); p_nd->m_value = r_new_val; if (bubble_up) { node_pointer p_parent = base_type::parent(p_nd); while (p_parent != 0 && Cmp_Fn::operator()(p_parent->m_value, p_nd->m_value)) { base_type::swap_with_parent(p_nd, p_parent); p_parent = base_type::parent(p_nd); } if (p_nd->m_p_prev_or_parent == 0) base_type::m_p_root = p_nd; m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) return; } base_type::bubble_to_top(p_nd); remove_parentless_node(p_nd); insert_node(p_nd); m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) } 8/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp000064400000010602152526447520017322 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/erase_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: pop() { PB_DS_ASSERT_VALID_COND((*this),true) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); if (m_p_max == 0) find_max(); _GLIBCXX_DEBUG_ASSERT(m_p_max != 0); node_pointer p_nd = m_p_max; remove_parentless_node(m_p_max); base_type::actual_erase_node(p_nd); m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_parentless_node(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(base_type::parent(p_nd) == 0); node_pointer p_cur_root = p_nd == base_type::m_p_root? p_nd->m_p_next_sibling : base_type::m_p_root; if (p_cur_root != 0) p_cur_root->m_p_prev_or_parent = 0; if (p_nd->m_p_prev_or_parent != 0) p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; node_pointer p_child = p_nd->m_p_l_child; if (p_child != 0) { p_child->m_p_prev_or_parent = 0; while (p_child->m_p_next_sibling != 0) p_child = p_child->m_p_next_sibling; } m_p_max = 0; base_type::m_p_root = join(p_cur_root, p_child); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: clear() { base_type::clear(); m_p_max = 0; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { PB_DS_ASSERT_VALID_COND((*this),true) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); base_type::bubble_to_top(it.m_p_nd); remove_parentless_node(it.m_p_nd); base_type::actual_erase_node(it.m_p_nd); m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID_COND((*this),true) if (base_type::empty()) { PB_DS_ASSERT_VALID_COND((*this),true) return 0; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); size_type ersd = 0; while (p_out != 0) { ++ersd; node_pointer p_next = p_out->m_p_next_sibling; base_type::actual_erase_node(p_out); p_out = p_next; } node_pointer p_cur = base_type::m_p_root; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; p_cur->m_p_l_child = p_cur->m_p_prev_or_parent = 0; p_cur->m_metadata = 0; p_cur->m_p_next_sibling = base_type::m_p_root; if (base_type::m_p_root != 0) base_type::m_p_root->m_p_prev_or_parent = p_cur; base_type::m_p_root = p_cur; base_type::m_p_root = fix(base_type::m_p_root); p_cur = p_next; } m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) return ersd; } 8/ext/pb_ds/detail/binomial_heap_base_/split_join_fn_imps.hpp000064400000012365152526447520020405 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/split_join_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) other.clear(); if (base_type::empty()) { PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) return; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); while (p_out != 0) { _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); --base_type::m_size; ++other.m_size; node_pointer p_next = p_out->m_p_next_sibling; p_out->m_p_l_child = p_out->m_p_prev_or_parent = 0; p_out->m_metadata = 0; p_out->m_p_next_sibling = other.m_p_root; if (other.m_p_root != 0) other.m_p_root->m_p_prev_or_parent = p_out; other.m_p_root = p_out; other.m_p_root = other.fix(other.m_p_root); p_out = p_next; } PB_DS_ASSERT_VALID_COND(other,true) node_pointer p_cur = base_type::m_p_root; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; p_cur->m_p_l_child = p_cur->m_p_prev_or_parent = 0; p_cur->m_metadata = 0; p_cur->m_p_next_sibling = base_type::m_p_root; if (base_type::m_p_root != 0) base_type::m_p_root->m_p_prev_or_parent = p_cur; base_type::m_p_root = p_cur; base_type::m_p_root = fix(base_type::m_p_root); p_cur = p_next; } m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) node_pointer p_other = other.m_p_root; if (p_other != 0) do { node_pointer p_next = p_other->m_p_next_sibling; std::swap(p_other->m_p_next_sibling, p_other->m_p_prev_or_parent); p_other = p_next; } while (p_other != 0); base_type::m_p_root = join(base_type::m_p_root, other.m_p_root); base_type::m_size += other.m_size; m_p_max = 0; other.m_p_root = 0; other.m_size = 0; other.m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: join(node_pointer p_lhs, node_pointer p_rhs) const { node_pointer p_ret = 0; node_pointer p_cur = 0; while (p_lhs != 0 || p_rhs != 0) { if (p_rhs == 0) { if (p_cur == 0) p_ret = p_cur = p_lhs; else { p_cur->m_p_next_sibling = p_lhs; p_lhs->m_p_prev_or_parent = p_cur; } p_cur = p_lhs = 0; } else if (p_lhs == 0 || p_rhs->m_metadata < p_lhs->m_metadata) { if (p_cur == 0) { p_ret = p_cur = p_rhs; p_rhs = p_rhs->m_p_prev_or_parent; } else { p_cur->m_p_next_sibling = p_rhs; p_rhs = p_rhs->m_p_prev_or_parent; p_cur->m_p_next_sibling->m_p_prev_or_parent = p_cur; p_cur = p_cur->m_p_next_sibling; } } else if (p_lhs->m_metadata < p_rhs->m_metadata) { if (p_cur == 0) p_ret = p_cur = p_lhs; else { p_cur->m_p_next_sibling = p_lhs; p_lhs->m_p_prev_or_parent = p_cur; p_cur = p_cur->m_p_next_sibling; } p_lhs = p_cur->m_p_next_sibling; } else { node_pointer p_next_rhs = p_rhs->m_p_prev_or_parent; p_rhs->m_p_next_sibling = p_lhs; p_lhs = fix(p_rhs); p_rhs = p_next_rhs; } } if (p_cur != 0) p_cur->m_p_next_sibling = 0; if (p_ret != 0) p_ret->m_p_prev_or_parent = 0; return p_ret; } 8/ext/pb_ds/detail/priority_queue_base_dispatch.hpp000064400000010054152526447520016527 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/priority_queue_base_dispatch.hpp * Contains an pqiative container dispatching base. */ #ifndef PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP #define PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP #define PB_DS_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);) #define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) #include #include #include #include #include #undef PB_DS_DEBUG_VERIFY #undef PB_DS_ASSERT_VALID namespace __gnu_pbds { namespace detail { /// Specialization for pairing_heap. template struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, pairing_heap_tag, null_type> { /// Dispatched type. typedef pairing_heap<_VTp, Cmp_Fn, _Alloc> type; }; /// Specialization for binomial_heap. template struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, binomial_heap_tag, null_type> { /// Dispatched type. typedef binomial_heap<_VTp, Cmp_Fn, _Alloc> type; }; /// Specialization for rc_binary_heap. template struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, rc_binomial_heap_tag, null_type> { /// Dispatched type. typedef rc_binomial_heap<_VTp, Cmp_Fn, _Alloc> type; }; /// Specialization for binary_heap. template struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, binary_heap_tag, null_type> { /// Dispatched type. typedef binary_heap<_VTp, Cmp_Fn, _Alloc> type; }; /// Specialization for thin_heap. template struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, thin_heap_tag, null_type> { /// Dispatched type. typedef thin_heap<_VTp, Cmp_Fn, _Alloc> type; }; //@} group pbds } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP 8/ext/pb_ds/detail/debug_map_base.hpp000064400000020771152526447520013515 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/debug_map_base.hpp * Contains a debug-mode base for all maps. */ #ifndef PB_DS_DEBUG_MAP_BASE_HPP #define PB_DS_DEBUG_MAP_BASE_HPP #ifdef _GLIBCXX_DEBUG #include #include #include #include #include #include namespace __gnu_pbds { namespace detail { // Need std::pair ostream extractor. template inline std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __out, const std::pair<_Tp1, _Tp2>& p) { return (__out << '(' << p.first << ',' << p.second << ')'); } #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ debug_map_base /// Debug base class. template class debug_map_base { private: typedef Const_Key_Reference key_const_reference; typedef std::_GLIBCXX_STD_C::list key_repository; typedef typename key_repository::size_type size_type; typedef typename key_repository::iterator iterator; typedef typename key_repository::const_iterator const_iterator; protected: debug_map_base(); debug_map_base(const PB_DS_CLASS_C_DEC&); ~debug_map_base(); inline void insert_new(key_const_reference); inline void erase_existing(key_const_reference); void clear(); inline void check_key_exists(key_const_reference, const char*, int) const; inline void check_key_does_not_exist(key_const_reference, const char*, int) const; inline void check_size(size_type, const char*, int) const; void swap(PB_DS_CLASS_C_DEC&); template void split(key_const_reference, Cmp_Fn, PB_DS_CLASS_C_DEC&); void join(PB_DS_CLASS_C_DEC&, bool with_cleanup = true); private: void assert_valid(const char*, int) const; const_iterator find(key_const_reference) const; iterator find(key_const_reference); key_repository m_keys; Eq_Fn m_eq; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: debug_map_base() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: debug_map_base(const PB_DS_CLASS_C_DEC& other) : m_keys(other.m_keys), m_eq(other.m_eq) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~debug_map_base() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_new(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) if (find(r_key) != m_keys.end()) { std::cerr << "insert_new key already present " << r_key << std::endl; std::abort(); } __try { m_keys.push_back(r_key); } __catch(...) { std::cerr << "insert_new " << r_key << std::endl; std::abort(); } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: erase_existing(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) iterator it = find(r_key); if (it == m_keys.end()) { std::cerr << "erase_existing" << r_key << std::endl; std::abort(); } m_keys.erase(it); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { PB_DS_ASSERT_VALID((*this)) m_keys.clear(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: check_key_exists(key_const_reference r_key, const char* __file, int __line) const { assert_valid(__file, __line); if (find(r_key) == m_keys.end()) { std::cerr << __file << ':' << __line << ": check_key_exists " << r_key << std::endl; std::abort(); } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: check_key_does_not_exist(key_const_reference r_key, const char* __file, int __line) const { assert_valid(__file, __line); if (find(r_key) != m_keys.end()) { using std::cerr; using std::endl; cerr << __file << ':' << __line << ": check_key_does_not_exist " << r_key << endl; std::abort(); } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: check_size(size_type size, const char* __file, int __line) const { assert_valid(__file, __line); const size_type keys_size = m_keys.size(); if (size != keys_size) { std::cerr << __file << ':' << __line << ": check_size " << size << " != " << keys_size << std::endl; std::abort(); } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) m_keys.swap(other.m_keys); std::swap(m_eq, other.m_eq); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) typedef const_iterator iterator_type; for (iterator_type it = m_keys.begin(); it != m_keys.end(); ++it) if (m_eq(*it, r_key)) return it; return m_keys.end(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) iterator it = m_keys.begin(); while (it != m_keys.end()) { if (m_eq(*it, r_key)) return it; ++it; } return it; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { const_iterator prime_it = m_keys.begin(); while (prime_it != m_keys.end()) { const_iterator sec_it = prime_it; ++sec_it; while (sec_it != m_keys.end()) { PB_DS_DEBUG_VERIFY(!m_eq(*sec_it, *prime_it)); PB_DS_DEBUG_VERIFY(!m_eq(*prime_it, *sec_it)); ++sec_it; } ++prime_it; } } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, Cmp_Fn cmp_fn, PB_DS_CLASS_C_DEC& other) { other.clear(); iterator it = m_keys.begin(); while (it != m_keys.end()) if (cmp_fn(r_key, *it)) { other.insert_new(*it); it = m_keys.erase(it); } else ++it; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other, bool with_cleanup) { iterator it = other.m_keys.begin(); while (it != other.m_keys.end()) { insert_new(*it); if (with_cleanup) it = other.m_keys.erase(it); else ++it; } _GLIBCXX_DEBUG_ASSERT(!with_cleanup || other.m_keys.empty()); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif #endif 8/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp000064400000010075152526447520017364 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/resize_fn_imps.hpp * Contains implementations of gp_ht_map_'s resize related functions. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: do_resize_if_needed() { if (!resize_base::is_resize_needed()) return false; resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: do_resize(size_type n) { resize_imp(resize_base::get_nearest_larger_size(n)); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: do_resize_if_needed_no_throw() { if (!resize_base::is_resize_needed()) return; __try { resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); } __catch(...) { } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize_imp(size_type new_size) { #ifdef PB_DS_REGRESSION typename _Alloc::group_adjustor adjust(m_num_e); #endif if (new_size == m_num_e) return; PB_DS_ASSERT_VALID((*this)) const size_type old_size = m_num_e; entry_array a_entries_resized = 0; // Following line might throw an exception. a_entries_resized = s_entry_allocator.allocate(new_size); ranged_probe_fn_base::notify_resized(new_size); m_num_e = new_size; for (size_type i = 0; i < m_num_e; ++i) a_entries_resized[i].m_stat = empty_entry_status; __try { resize_imp(a_entries_resized, old_size); } __catch(...) { erase_all_valid_entries(a_entries_resized, new_size); m_num_e = old_size; s_entry_allocator.deallocate(a_entries_resized, new_size); ranged_probe_fn_base::notify_resized(old_size); __throw_exception_again; } // At this point no exceptions can be thrown. _GLIBCXX_DEBUG_ONLY(assert_entry_array_valid(a_entries_resized, traits_base::m_store_extra_indicator, __FILE__, __LINE__);) Resize_Policy::notify_resized(new_size); erase_all_valid_entries(m_entries, old_size); s_entry_allocator.deallocate(m_entries, old_size); m_entries = a_entries_resized; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize_imp(entry_array a_entries_resized, size_type old_size) { for (size_type pos = 0; pos < old_size; ++pos) if (m_entries[pos].m_stat == valid_entry_status) resize_imp_reassign(m_entries + pos, a_entries_resized, traits_base::m_store_extra_indicator); } #include #include 8/ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp000064400000005072152526447520022300 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s resize related functions, when the * hash value is not stored. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: resize_imp_reassign(entry_pointer p_e, entry_array a_entries_resized, false_type) { key_const_reference r_key = PB_DS_V2F(p_e->m_value); size_type hash = ranged_probe_fn_base::operator()(r_key); size_type i; for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); entry_pointer p_new_e = a_entries_resized + pos; switch(p_new_e->m_stat) { case empty_entry_status: new (&p_new_e->m_value) value_type(p_e->m_value); p_new_e->m_stat = valid_entry_status; return; case erased_entry_status: _GLIBCXX_DEBUG_ASSERT(0); break; case valid_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; } __throw_insert_error(); } 8/ext/pb_ds/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp000064400000005505152526447520022077 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s erase related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase_imp(key_const_reference r_key, false_type) { PB_DS_ASSERT_VALID((*this)) size_type hash = ranged_probe_fn_base::operator()(r_key); size_type i; resize_base::notify_erase_search_start(); for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return false; } break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_erase_search_end(); erase_entry(p_e); do_resize_if_needed_no_throw(); return true; } break; case erased_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_erase_search_collision(); } resize_base::notify_erase_search_end(); return false; } 8/ext/pb_ds/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp000064400000007301152526447520022300 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s insert related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: find_ins_pos(key_const_reference r_key, false_type) { size_type hash = ranged_probe_fn_base::operator()(r_key); size_type i; /* The insertion position is initted to a non-legal value to indicate * that it has not been initted yet. */ size_type ins_pos = m_num_e; resize_base::notify_insert_search_start(); for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); _GLIBCXX_DEBUG_ASSERT(pos < m_num_e); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_insert_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return (ins_pos == m_num_e) ? pos : ins_pos; } break; case erased_entry_status: if (ins_pos == m_num_e) ins_pos = pos; break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_insert_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) return pos; } break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_insert_search_collision(); } resize_base::notify_insert_search_end(); if (ins_pos == m_num_e) __throw_insert_error(); return ins_pos; } PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert_imp(const_reference r_val, false_type) { key_const_reference r_key = PB_DS_V2F(r_val); const size_type pos = find_ins_pos(r_key, traits_base::m_store_extra_indicator); if (m_entries[pos].m_stat == valid_entry_status) { PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(&(m_entries + pos)->m_value, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return std::make_pair(insert_new_imp(r_val, pos), true); } 8/ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hpp000064400000004570152526447520017164 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/trace_fn_imps.hpp * Contains implementations of gp_ht_map_'s trace-mode functions. */ #ifdef PB_DS_HT_MAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << static_cast(m_num_e) << " " << static_cast(m_num_used_e) << std::endl; for (size_type i = 0; i < m_num_e; ++i) { std::cerr << static_cast(i) << " "; switch(m_entries[i].m_stat) { case empty_entry_status: std::cerr << ""; break; case erased_entry_status: std::cerr << ""; break; case valid_entry_status: std::cerr << PB_DS_V2F(m_entries[i].m_value); break; default: _GLIBCXX_DEBUG_ASSERT(0); }; std::cerr << std::endl; } } #endif // #ifdef PB_DS_HT_MAP_TRACE_ 8/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp000064400000014716152526447520022734 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/constructor_destructor_fn_imps.hpp * Contains implementations of gp_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_allocator PB_DS_CLASS_C_DEC::s_entry_allocator; PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME() : ranged_probe_fn_base(resize_base::get_nearest_larger_size(1)), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn) : ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn) : hash_eq_fn_base(r_eq_fn), ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Probe_Fn& r_comb_hash_fn) : hash_eq_fn_base(r_eq_fn), ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, r_comb_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Probe_Fn& comb_hash_fn, const Probe_Fn& prober) : hash_eq_fn_base(r_eq_fn), ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, comb_hash_fn, prober), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Probe_Fn& comb_hash_fn, const Probe_Fn& prober, const Resize_Policy& r_resize_policy) : hash_eq_fn_base(r_eq_fn), resize_base(r_resize_policy), ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, comb_hash_fn, prober), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const PB_DS_CLASS_C_DEC& other) : #ifdef _GLIBCXX_DEBUG debug_base(other), #endif hash_eq_fn_base(other), resize_base(other), ranged_probe_fn_base(other), m_num_e(other.m_num_e), m_num_used_e(other.m_num_used_e), m_entries(s_entry_allocator.allocate(m_num_e)) { for (size_type i = 0; i < m_num_e; ++i) m_entries[i].m_stat = (entry_status)empty_entry_status; __try { for (size_type i = 0; i < m_num_e; ++i) { m_entries[i].m_stat = other.m_entries[i].m_stat; if (m_entries[i].m_stat == valid_entry_status) new (m_entries + i) entry(other.m_entries[i]); } } __catch(...) { deallocate_all(); __throw_exception_again; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_GP_HASH_NAME() { deallocate_all(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) std::swap(m_num_e, other.m_num_e); std::swap(m_num_used_e, other.m_num_used_e); std::swap(m_entries, other.m_entries); ranged_probe_fn_base::swap(other); hash_eq_fn_base::swap(other); resize_base::swap(other); _GLIBCXX_DEBUG_ONLY(debug_base::swap(other)); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: deallocate_all() { clear(); erase_all_valid_entries(m_entries, m_num_e); s_entry_allocator.deallocate(m_entries, m_num_e); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_all_valid_entries(entry_array a_entries_resized, size_type len) { for (size_type pos = 0; pos < len; ++pos) { entry_pointer p_e = &a_entries_resized[pos]; if (p_e->m_stat == valid_entry_status) p_e->m_value.~value_type(); } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { Resize_Policy::notify_resized(m_num_e); Resize_Policy::notify_cleared(); ranged_probe_fn_base::notify_resized(m_num_e); for (size_type i = 0; i < m_num_e; ++i) m_entries[i].m_stat = empty_entry_status; } 8/ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hpp000064400000005144152526447520020704 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/policy_access_fn_imps.hpp * Contains implementations of gp_ht_map_'s policy agpess * functions. */ PB_DS_CLASS_T_DEC Hash_Fn& PB_DS_CLASS_C_DEC:: get_hash_fn() { return *this; } PB_DS_CLASS_T_DEC const Hash_Fn& PB_DS_CLASS_C_DEC:: get_hash_fn() const { return *this; } PB_DS_CLASS_T_DEC Eq_Fn& PB_DS_CLASS_C_DEC:: get_eq_fn() { return *this; } PB_DS_CLASS_T_DEC const Eq_Fn& PB_DS_CLASS_C_DEC:: get_eq_fn() const { return *this; } PB_DS_CLASS_T_DEC Probe_Fn& PB_DS_CLASS_C_DEC:: get_probe_fn() { return *this; } PB_DS_CLASS_T_DEC const Probe_Fn& PB_DS_CLASS_C_DEC:: get_probe_fn() const { return *this; } PB_DS_CLASS_T_DEC Comb_Probe_Fn& PB_DS_CLASS_C_DEC:: get_comb_probe_fn() { return *this; } PB_DS_CLASS_T_DEC const Comb_Probe_Fn& PB_DS_CLASS_C_DEC:: get_comb_probe_fn() const { return *this; } PB_DS_CLASS_T_DEC Resize_Policy& PB_DS_CLASS_C_DEC:: get_resize_policy() { return *this; } PB_DS_CLASS_T_DEC const Resize_Policy& PB_DS_CLASS_C_DEC:: get_resize_policy() const { return *this; } 8/ext/pb_ds/detail/gp_hash_table_map_/find_store_hash_fn_imps.hpp000064400000003364152526447520021225 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/find_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s insert related functions, * when the hash value is stored. */ 8/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp000064400000004074152526447520017020 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/info_fn_imps.hpp * Contains implementations of gp_ht_map_'s entire container info related * functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_num_used_e; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_entry_allocator.max_size(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (size() == 0); } 8/ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hpp000064400000004656152526447520017013 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/find_fn_imps.hpp * Contains implementations of gp_ht_map_'s find related functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) return find_key_pointer(r_key, traits_base::m_store_extra_indicator); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) return const_cast(*this).find_key_pointer(r_key, traits_base::m_store_extra_indicator); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find_end() { return 0; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find_end() const { return 0; } 8/ext/pb_ds/detail/gp_hash_table_map_/find_no_store_hash_fn_imps.hpp000064400000003604152526447520021716 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/find_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s find related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::pointer PB_DS_CLASS_C_DEC:: find_key_pointer(key_const_reference r_key, false_type) 8/ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hpp000064400000005073152526447520017716 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/iterator_fn_imps.hpp * Contains implementations of gp_ht_map_'s iterators related functions, e.g., * begin(). */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC::s_end_it; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC::s_const_end_it; PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { pointer_ p_value; size_type pos; get_start_it_state(p_value, pos); return iterator(p_value, pos, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return s_end_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { const_pointer_ p_value; size_type pos; get_start_it_state(p_value, pos); return const_iterator(p_value, pos, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return s_const_end_it; } 8/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp000064400000004335152526447520025147 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: constructor_insert_new_imp(mapped_const_reference r_val, size_type pos, true_type) { _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); entry* const p_e = m_entries + pos; new (&p_e->m_value) mapped_value_type(r_val); p_e->m_hash = ranged_probe_fn_base::operator()(PB_DS_V2F(r_val)).second; p_e->m_stat = valid_entry_status; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(p_e->m_value.first);) } 8/ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hpp000064400000004176152526447520017156 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/debug_fn_imps.hpp * Contains implementations of gp_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { debug_base::check_size(m_num_used_e, __file, __line); assert_entry_array_valid(m_entries, traits_base::m_store_extra_indicator, __file, __line); } #include #include #endif 8/ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hpp000064400000003550152526447520017367 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/insert_fn_imps.hpp * Contains implementations of gp_ht_map_'s insert related functions. */ #include #include 8/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp000064400000047656152526447520016464 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/gp_ht_map_.hpp * Contains an implementation class for general probing hash. */ #include #include #include #include #include #include #ifdef PB_DS_HT_MAP_TRACE_ #include #endif #ifdef _GLIBCXX_DEBUG #include #endif #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_GP_HASH_NAME gp_ht_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_GP_HASH_NAME gp_ht_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_GP_HASH_NAME #define PB_DS_HASH_EQ_FN_C_DEC \ hash_eq_fn #define PB_DS_RANGED_PROBE_FN_C_DEC \ ranged_probe_fn #define PB_DS_GP_HASH_TRAITS_BASE \ types_traits #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base::other::const_reference> #endif /** * A general-probing hash-based container. * * * @ingroup hash-detail * * @tparam Key Key type. * * @tparam Mapped Map type. * * @tparam Hash_Fn Hashing functor. * Default is __gnu_cxx::hash. * * @tparam Eq_Fn Equal functor. * Default std::equal_to * * @tparam _Alloc Allocator type. * * @tparam Store_Hash If key type stores extra metadata. * Defaults to false. * * @tparam Comb_Probe_Fn Combining probe functor. * If Hash_Fn is not null_type, then this * is the ranged-probe functor; otherwise, * this is the range-hashing functor. * XXX See Design::Hash-Based Containers::Hash Policies. * Default direct_mask_range_hashing. * * @tparam Probe_Fn Probe functor. * Defaults to linear_probe_fn, * also quadratic_probe_fn. * * @tparam Resize_Policy Resizes hash. * Defaults to hash_standard_resize_policy, * using hash_exponential_size_policy and * hash_load_check_resize_trigger. * * * Bases are: detail::hash_eq_fn, Resize_Policy, detail::ranged_probe_fn, * detail::types_traits. (Optional: detail::debug_map_base.) */ template class PB_DS_GP_HASH_NAME : #ifdef _GLIBCXX_DEBUG protected PB_DS_DEBUG_MAP_BASE_C_DEC, #endif public PB_DS_HASH_EQ_FN_C_DEC, public Resize_Policy, public PB_DS_RANGED_PROBE_FN_C_DEC, public PB_DS_GP_HASH_TRAITS_BASE { private: typedef PB_DS_GP_HASH_TRAITS_BASE traits_base; typedef typename traits_base::value_type value_type_; typedef typename traits_base::pointer pointer_; typedef typename traits_base::const_pointer const_pointer_; typedef typename traits_base::reference reference_; typedef typename traits_base::const_reference const_reference_; typedef typename traits_base::comp_hash comp_hash; enum entry_status { empty_entry_status, valid_entry_status, erased_entry_status } __attribute__ ((__packed__)); struct entry : public traits_base::stored_data_type { entry_status m_stat; }; typedef typename _Alloc::template rebind::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; typedef typename entry_allocator::const_pointer const_entry_pointer; typedef typename entry_allocator::reference entry_reference; typedef typename entry_allocator::const_reference const_entry_reference; typedef typename entry_allocator::pointer entry_array; typedef PB_DS_RANGED_PROBE_FN_C_DEC ranged_probe_fn_base; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif typedef PB_DS_HASH_EQ_FN_C_DEC hash_eq_fn_base; typedef Resize_Policy resize_base; #define PB_DS_GEN_POS typename _Alloc::size_type #include #include #include #include #undef PB_DS_GEN_POS public: typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Hash_Fn hash_fn; typedef Eq_Fn eq_fn; typedef Probe_Fn probe_fn; typedef Comb_Probe_Fn comb_probe_fn; typedef Resize_Policy resize_policy; /// Value stores hash, true or false. enum { store_hash = Store_Hash }; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef point_iterator_ point_iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef point_const_iterator_ point_iterator; #endif typedef point_const_iterator_ point_const_iterator; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef iterator_ iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef const_iterator_ iterator; #endif typedef const_iterator_ const_iterator; PB_DS_GP_HASH_NAME(); PB_DS_GP_HASH_NAME(const PB_DS_CLASS_C_DEC&); PB_DS_GP_HASH_NAME(const Hash_Fn&); PB_DS_GP_HASH_NAME(const Hash_Fn&, const Eq_Fn&); PB_DS_GP_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&); PB_DS_GP_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&, const Probe_Fn&); PB_DS_GP_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&, const Probe_Fn&, const Resize_Policy&); template void copy_from_range(It, It); virtual ~PB_DS_GP_HASH_NAME(); void swap(PB_DS_CLASS_C_DEC&); inline size_type size() const; inline size_type max_size() const; /// True if size() == 0. inline bool empty() const; /// Return current hash_fn. Hash_Fn& get_hash_fn(); /// Return current const hash_fn. const Hash_Fn& get_hash_fn() const; /// Return current eq_fn. Eq_Fn& get_eq_fn(); /// Return current const eq_fn. const Eq_Fn& get_eq_fn() const; /// Return current probe_fn. Probe_Fn& get_probe_fn(); /// Return current const probe_fn. const Probe_Fn& get_probe_fn() const; /// Return current comb_probe_fn. Comb_Probe_Fn& get_comb_probe_fn(); /// Return current const comb_probe_fn. const Comb_Probe_Fn& get_comb_probe_fn() const; /// Return current resize_policy. Resize_Policy& get_resize_policy(); /// Return current const resize_policy. const Resize_Policy& get_resize_policy() const; inline std::pair insert(const_reference r_val) { _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid(__FILE__, __LINE__);) return insert_imp(r_val, traits_base::m_store_extra_indicator); } inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR return subscript_imp(r_key, traits_base::m_store_extra_indicator); #else insert(r_key); return traits_base::s_null_type; #endif } inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline point_iterator find_end(); inline point_const_iterator find_end() const; inline bool erase(key_const_reference); template inline size_type erase_if(Pred); void clear(); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_HT_MAP_TRACE_ void trace() const; #endif private: #ifdef PB_DS_DATA_TRUE_INDICATOR friend class iterator_; #endif friend class const_iterator_; void deallocate_all(); void initialize(); void erase_all_valid_entries(entry_array, size_type); inline bool do_resize_if_needed(); inline void do_resize_if_needed_no_throw(); void resize_imp(size_type); virtual void do_resize(size_type); void resize_imp(entry_array, size_type); inline void resize_imp_reassign(entry_pointer, entry_array, false_type); inline void resize_imp_reassign(entry_pointer, entry_array, true_type); inline size_type find_ins_pos(key_const_reference, false_type); inline comp_hash find_ins_pos(key_const_reference, true_type); inline std::pair insert_imp(const_reference, false_type); inline std::pair insert_imp(const_reference, true_type); inline pointer insert_new_imp(const_reference r_val, size_type pos) { _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); if (do_resize_if_needed()) pos = find_ins_pos(PB_DS_V2F(r_val), traits_base::m_store_extra_indicator); _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); entry* const p_e = m_entries + pos; new (&p_e->m_value) value_type(r_val); p_e->m_stat = valid_entry_status; resize_base::notify_inserted(++m_num_used_e); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(p_e->m_value));) _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return &p_e->m_value; } inline pointer insert_new_imp(const_reference r_val, comp_hash& r_pos_hash_pair) { _GLIBCXX_DEBUG_ASSERT(m_entries[r_pos_hash_pair.first].m_stat != valid_entry_status); if (do_resize_if_needed()) r_pos_hash_pair = find_ins_pos(PB_DS_V2F(r_val), traits_base::m_store_extra_indicator); _GLIBCXX_DEBUG_ASSERT(m_entries[r_pos_hash_pair.first].m_stat != valid_entry_status); entry* const p_e = m_entries + r_pos_hash_pair.first; new (&p_e->m_value) value_type(r_val); p_e->m_hash = r_pos_hash_pair.second; p_e->m_stat = valid_entry_status; resize_base::notify_inserted(++m_num_used_e); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(p_e->m_value));) _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return &p_e->m_value; } #ifdef PB_DS_DATA_TRUE_INDICATOR inline mapped_reference subscript_imp(key_const_reference key, false_type) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) const size_type pos = find_ins_pos(key, traits_base::m_store_extra_indicator); entry_pointer p_e = &m_entries[pos]; if (p_e->m_stat != valid_entry_status) return insert_new_imp(value_type(key, mapped_type()), pos)->second; PB_DS_CHECK_KEY_EXISTS(key) return p_e->m_value.second; } inline mapped_reference subscript_imp(key_const_reference key, true_type) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) comp_hash pos_hash_pair = find_ins_pos(key, traits_base::m_store_extra_indicator); if (m_entries[pos_hash_pair.first].m_stat != valid_entry_status) return insert_new_imp(value_type(key, mapped_type()), pos_hash_pair)->second; PB_DS_CHECK_KEY_EXISTS(key) return (m_entries + pos_hash_pair.first)->m_value.second; } #endif inline pointer find_key_pointer(key_const_reference key, false_type) { const size_type hash = ranged_probe_fn_base::operator()(key); resize_base::notify_find_search_start(); // Loop until entry is found or until all possible entries accessed. for (size_type i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(key, hash, i); entry* const p_e = m_entries + pos; switch (p_e->m_stat) { case empty_entry_status: { resize_base::notify_find_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) return 0; } break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), key)) { resize_base::notify_find_search_end(); PB_DS_CHECK_KEY_EXISTS(key) return pointer(&p_e->m_value); } break; case erased_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_find_search_collision(); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) resize_base::notify_find_search_end(); return 0; } inline pointer find_key_pointer(key_const_reference key, true_type) { comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(key); resize_base::notify_find_search_start(); // Loop until entry is found or until all possible entries accessed. for (size_type i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(key, pos_hash_pair.second, i); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_find_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) return 0; } break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, key, pos_hash_pair.second)) { resize_base::notify_find_search_end(); PB_DS_CHECK_KEY_EXISTS(key) return pointer(&p_e->m_value); } break; case erased_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_find_search_collision(); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) resize_base::notify_find_search_end(); return 0; } inline bool erase_imp(key_const_reference, true_type); inline bool erase_imp(key_const_reference, false_type); inline void erase_entry(entry_pointer); #ifdef PB_DS_DATA_TRUE_INDICATOR void inc_it_state(pointer& r_p_value, size_type& r_pos) const { inc_it_state((mapped_const_pointer& )r_p_value, r_pos); } #endif void inc_it_state(const_pointer& r_p_value, size_type& r_pos) const { _GLIBCXX_DEBUG_ASSERT(r_p_value != 0); for (++r_pos; r_pos < m_num_e; ++r_pos) { const_entry_pointer p_e =& m_entries[r_pos]; if (p_e->m_stat == valid_entry_status) { r_p_value =& p_e->m_value; return; } } r_p_value = 0; } void get_start_it_state(const_pointer& r_p_value, size_type& r_pos) const { for (r_pos = 0; r_pos < m_num_e; ++r_pos) { const_entry_pointer p_e = &m_entries[r_pos]; if (p_e->m_stat == valid_entry_status) { r_p_value = &p_e->m_value; return; } } r_p_value = 0; } void get_start_it_state(pointer& r_p_value, size_type& r_pos) { for (r_pos = 0; r_pos < m_num_e; ++r_pos) { entry_pointer p_e = &m_entries[r_pos]; if (p_e->m_stat == valid_entry_status) { r_p_value = &p_e->m_value; return; } } r_p_value = 0; } #ifdef _GLIBCXX_DEBUG void assert_entry_array_valid(const entry_array, false_type, const char*, int) const; void assert_entry_array_valid(const entry_array, true_type, const char*, int) const; #endif static entry_allocator s_entry_allocator; static iterator s_end_it; static const_iterator s_const_end_it; size_type m_num_e; size_type m_num_used_e; entry_pointer m_entries; enum { store_hash_ok = !Store_Hash || !is_same::value }; PB_DS_STATIC_ASSERT(sth, store_hash_ok); }; #include #include #include #include #include #include #include #include #include #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_HASH_EQ_FN_C_DEC #undef PB_DS_RANGED_PROBE_FN_C_DEC #undef PB_DS_GP_HASH_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #undef PB_DS_GP_HASH_NAME } // namespace detail } // namespace __gnu_pbds 8/ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hpp000064400000006204152526447520017161 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/erase_fn_imps.hpp * Contains implementations of gp_ht_map_'s erase related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: erase_entry(entry_pointer p_e) { _GLIBCXX_DEBUG_ASSERT(p_e->m_stat = valid_entry_status); _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_e->m_value));) p_e->m_value.~value_type(); p_e->m_stat = erased_entry_status; _GLIBCXX_DEBUG_ASSERT(m_num_used_e > 0); resize_base::notify_erased(--m_num_used_e); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { for (size_type pos = 0; pos < m_num_e; ++pos) { entry_pointer p_e = &m_entries[pos]; if (p_e->m_stat == valid_entry_status) erase_entry(p_e); } do_resize_if_needed_no_throw(); resize_base::notify_cleared(); } PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) size_type num_ersd = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { entry_pointer p_e = &m_entries[pos]; if (p_e->m_stat == valid_entry_status) if (pred(p_e->m_value)) { ++num_ersd; erase_entry(p_e); } } do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { return erase_imp(r_key, traits_base::m_store_extra_indicator); } #include #include 8/ext/pb_ds/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp000064400000004711152526447520022064 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_array_valid(const entry_array a_entries, false_type, const char* __file, int __line) const { size_type iterated_num_used_e = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { const_entry_pointer p_e = &a_entries[pos]; switch(p_e->m_stat) { case empty_entry_status: case erased_entry_status: break; case valid_entry_status: { key_const_reference r_key = PB_DS_V2F(p_e->m_value); debug_base::check_key_exists(r_key, __file, __line); ++iterated_num_used_e; break; } default: PB_DS_DEBUG_VERIFY(0); }; } PB_DS_DEBUG_VERIFY(iterated_num_used_e == m_num_used_e); } #endif 8/ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp000064400000005133152526447520021602 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/resize_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s resize related functions, when the * hash value is stored. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: resize_imp_reassign(entry_pointer p_e, entry_array a_entries_resized, true_type) { key_const_reference r_key = PB_DS_V2F(p_e->m_value); size_type hash = ranged_probe_fn_base::operator()(r_key, p_e->m_hash); size_type i; for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); entry_pointer p_new_e = a_entries_resized + pos; switch(p_new_e->m_stat) { case empty_entry_status: new (&p_new_e->m_value) value_type(p_e->m_value); p_new_e->m_hash = hash; p_new_e->m_stat = valid_entry_status; return; case erased_entry_status: _GLIBCXX_DEBUG_ASSERT(0); break; case valid_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; } __throw_insert_error(); } 8/ext/pb_ds/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp000064400000007765152526447520021622 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/insert_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s find related functions, * when the hash value is stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::comp_hash PB_DS_CLASS_C_DEC:: find_ins_pos(key_const_reference r_key, true_type) { PB_DS_ASSERT_VALID((*this)) comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); size_type i; /* The insertion position is initted to a non-legal value to indicate * that it has not been initted yet. */ size_type ins_pos = m_num_e; resize_base::notify_insert_search_start(); for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, pos_hash_pair.second, i); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_insert_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return ((ins_pos == m_num_e) ? std::make_pair(pos, pos_hash_pair.second) : std::make_pair(ins_pos, pos_hash_pair.second)); } break; case erased_entry_status: if (ins_pos == m_num_e) ins_pos = pos; break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, r_key, pos_hash_pair.second)) { resize_base::notify_insert_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(pos, pos_hash_pair.second); } break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_insert_search_collision(); } resize_base::notify_insert_search_end(); if (ins_pos == m_num_e) __throw_insert_error(); return std::make_pair(ins_pos, pos_hash_pair.second); } PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert_imp(const_reference r_val, true_type) { key_const_reference r_key = PB_DS_V2F(r_val); comp_hash pos_hash_pair = find_ins_pos(r_key, traits_base::m_store_extra_indicator); _GLIBCXX_DEBUG_ASSERT(pos_hash_pair.first < m_num_e); entry_pointer p_e =& m_entries[pos_hash_pair.first]; if (p_e->m_stat == valid_entry_status) { PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(&p_e->m_value, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return std::make_pair(insert_new_imp(r_val, pos_hash_pair), true); } 8/ext/pb_ds/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp000064400000005125152526447520021370 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/debug_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_array_valid(const entry_array a_entries, true_type, const char* __file, int __line) const { size_type iterated_num_used_e = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { const_entry_pointer p_e =& a_entries[pos]; switch(p_e->m_stat) { case empty_entry_status: case erased_entry_status: break; case valid_entry_status: { key_const_reference r_key = PB_DS_V2F(p_e->m_value); debug_base::check_key_exists(r_key, __file, __line); const comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); PB_DS_DEBUG_VERIFY(p_e->m_hash == pos_hash_pair.second); ++iterated_num_used_e; break; } default: PB_DS_DEBUG_VERIFY(0); }; } PB_DS_DEBUG_VERIFY(iterated_num_used_e == m_num_used_e); } #endif 8/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp000064400000004232152526447520025637 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: constructor_insert_new_imp(mapped_const_reference r_val, size_type pos, false_type) { _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status)k; entry* const p_e = m_entries + pos; new (&p_e->m_value) mapped_value_type(r_val); p_e->m_stat = valid_entry_status; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(p_e->m_value.first);) } 8/ext/pb_ds/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp000064400000005547152526447520021411 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/erase_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s erase related functions, * when the hash value is stored. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase_imp(key_const_reference r_key, true_type) { const comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); size_type i; resize_base::notify_erase_search_start(); for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, pos_hash_pair.second, i); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return false; } break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, r_key, pos_hash_pair.second)) { resize_base::notify_erase_search_end(); erase_entry(p_e); do_resize_if_needed_no_throw(); return true; } break; case erased_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_erase_search_collision(); } resize_base::notify_erase_search_end(); return false; } 8/ext/pb_ds/detail/rc_binomial_heap_/trace_fn_imps.hpp000064400000003560152526447520017020 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/trace_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { base_type::trace(); m_rc.trace(); } #endif // #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ 8/ext/pb_ds/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp000064400000004643152526447520022753 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: rc_binomial_heap() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: rc_binomial_heap(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: rc_binomial_heap(const PB_DS_CLASS_C_DEC& other) : base_type(other) { make_binomial_heap(); base_type::find_max(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~rc_binomial_heap() { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) base_type::swap(other); m_rc.swap(other.m_rc); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } 8/ext/pb_ds/detail/rc_binomial_heap_/debug_fn_imps.hpp000064400000006722152526447520017013 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/debug_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(false, __file, __line); if (!base_type::empty()) { PB_DS_DEBUG_VERIFY(base_type::m_p_max != 0); base_type::assert_max(__file, __line); } m_rc.assert_valid(__file, __line); if (m_rc.empty()) { base_type::assert_valid(true, __file, __line); PB_DS_DEBUG_VERIFY(next_2_pointer(base_type::m_p_root) == 0); return; } node_const_pointer p_nd = next_2_pointer(base_type::m_p_root); typename rc_t::const_iterator it = m_rc.end(); --it; while (p_nd != 0) { PB_DS_DEBUG_VERIFY(*it == p_nd); node_const_pointer p_next = p_nd->m_p_next_sibling; PB_DS_DEBUG_VERIFY(p_next != 0); PB_DS_DEBUG_VERIFY(p_nd->m_metadata == p_next->m_metadata); PB_DS_DEBUG_VERIFY(p_next->m_p_next_sibling == 0 || p_next->m_metadata < p_next->m_p_next_sibling->m_metadata); --it; p_nd = next_2_pointer(next_after_0_pointer(p_nd)); } PB_DS_DEBUG_VERIFY(it + 1 == m_rc.begin()); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_const_pointer PB_DS_CLASS_C_DEC:: next_2_pointer(node_const_pointer p_nd) { if (p_nd == 0) return 0; node_pointer p_next = p_nd->m_p_next_sibling; if (p_next == 0) return 0; if (p_nd->m_metadata == p_next->m_metadata) return p_nd; return next_2_pointer(p_next); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_const_pointer PB_DS_CLASS_C_DEC:: next_after_0_pointer(node_const_pointer p_nd) { if (p_nd == 0) return 0; node_pointer p_next = p_nd->m_p_next_sibling; if (p_next == 0) return 0; if (p_nd->m_metadata < p_next->m_metadata) return p_next; return next_after_0_pointer(p_next); } #endif 8/ext/pb_ds/detail/rc_binomial_heap_/insert_fn_imps.hpp000064400000010215152526447520017221 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/insert_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) make_0_exposed(); PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = base_type::get_new_node_for_insert(r_val); p_nd->m_p_l_child = p_nd->m_p_prev_or_parent = 0; p_nd->m_metadata = 0; if (base_type::m_p_max == 0 || Cmp_Fn::operator()(base_type::m_p_max->m_value, r_val)) base_type::m_p_max = p_nd; p_nd->m_p_next_sibling = base_type::m_p_root; if (base_type::m_p_root != 0) base_type::m_p_root->m_p_prev_or_parent = p_nd; base_type::m_p_root = p_nd; if (p_nd->m_p_next_sibling != 0&& p_nd->m_p_next_sibling->m_metadata == 0) m_rc.push(p_nd); PB_DS_ASSERT_VALID((*this)) return point_iterator(p_nd); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID((*this)) make_binomial_heap(); base_type::modify(it, r_new_val); base_type::find_max(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: link_with_next_sibling(node_pointer p_nd) { node_pointer p_next = p_nd->m_p_next_sibling; _GLIBCXX_DEBUG_ASSERT(p_next != 0); _GLIBCXX_DEBUG_ASSERT(p_next->m_p_prev_or_parent == p_nd); if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) { p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; if (p_next->m_p_prev_or_parent == 0) base_type::m_p_root = p_next; else p_next->m_p_prev_or_parent->m_p_next_sibling = p_next; if (base_type::m_p_max == p_nd) base_type::m_p_max = p_next; base_type::make_child_of(p_nd, p_next); ++p_next->m_metadata; return p_next; } p_nd->m_p_next_sibling = p_next->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; if (base_type::m_p_max == p_next) base_type::m_p_max = p_nd; base_type::make_child_of(p_next, p_nd); ++p_nd->m_metadata; return p_nd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: make_0_exposed() { if (m_rc.empty()) return; node_pointer p_nd = m_rc.top(); m_rc.pop(); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling != 0); _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata); node_pointer p_res = link_with_next_sibling(p_nd); if (p_res->m_p_next_sibling != 0&& p_res->m_metadata == p_res->m_p_next_sibling->m_metadata) m_rc.push(p_res); } 8/ext/pb_ds/detail/rc_binomial_heap_/erase_fn_imps.hpp000064400000005511152526447520017017 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/erase_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: pop() { make_binomial_heap(); _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); base_type::pop(); base_type::find_max(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { base_type::clear(); m_rc.clear(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: make_binomial_heap() { node_pointer p_nd = base_type::m_p_root; while (p_nd != 0) { node_pointer p_next = p_nd->m_p_next_sibling; if (p_next == 0) p_nd = p_next; else if (p_nd->m_metadata == p_next->m_metadata) p_nd = link_with_next_sibling(p_nd); else if (p_nd->m_metadata < p_next->m_metadata) p_nd = p_next; #ifdef _GLIBCXX_DEBUG else _GLIBCXX_DEBUG_ASSERT(0); #endif } m_rc.clear(); } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { make_binomial_heap(); const size_type ersd = base_type::erase_if(pred); base_type::find_max(); PB_DS_ASSERT_VALID((*this)) return ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { make_binomial_heap(); base_type::erase(it); base_type::find_max(); } 8/ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hpp000064400000012267152526447520017625 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/rc_binomial_heap_.hpp * Contains an implementation for redundant-counter binomial heap. */ #include #include #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ rc_binomial_heap #define PB_DS_RC_C_DEC \ rc::node, _Alloc> /** * Redundant-counter binomial heap. * * @ingroup heap-detail */ template class rc_binomial_heap : public binomial_heap_base { private: typedef binomial_heap_base base_type; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::node_const_pointer node_const_pointer; typedef PB_DS_RC_C_DEC rc_t; public: typedef Value_Type value_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::cmp_fn cmp_fn; typedef typename base_type::allocator_type allocator_type; rc_binomial_heap(); rc_binomial_heap(const Cmp_Fn&); rc_binomial_heap(const PB_DS_CLASS_C_DEC&); ~rc_binomial_heap(); void swap(PB_DS_CLASS_C_DEC&); inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline void pop(); void erase(point_iterator); inline void clear(); template size_type erase_if(Pred); template void split(Pred, PB_DS_CLASS_C_DEC&); void join(PB_DS_CLASS_C_DEC&); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ void trace() const; #endif private: inline node_pointer link_with_next_sibling(node_pointer); void make_0_exposed(); void make_binomial_heap(); #ifdef _GLIBCXX_DEBUG static node_const_pointer next_2_pointer(node_const_pointer); static node_const_pointer next_after_0_pointer(node_const_pointer); #endif rc_t m_rc; }; #include #include #include #include #include #include #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_RC_C_DEC } // namespace detail } // namespace __gnu_pbds 8/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp000064400000014171152526447520014613 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/rc.hpp * Contains a redundant (binary counter). */ #ifndef PB_DS_RC_HPP #define PB_DS_RC_HPP namespace __gnu_pbds { namespace detail { /// Redundant binary counter. template class rc { private: typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef _Node node; typedef typename _Alloc::template rebind __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; typedef typename _Alloc::template rebind __rebind_np; typedef typename __rebind_np::other::pointer entry_pointer; typedef typename __rebind_np::other::const_pointer entry_const_pointer; enum { max_entries = sizeof(size_type) << 3 }; public: typedef node_pointer entry; typedef entry_const_pointer const_iterator; rc(); rc(const rc&); inline void swap(rc&); inline void push(entry); inline node_pointer top() const; inline void pop(); inline bool empty() const; inline size_type size() const; void clear(); const const_iterator begin() const; const const_iterator end() const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ void trace() const; #endif private: node_pointer m_a_entries[max_entries]; size_type m_over_top; }; template rc<_Node, _Alloc>:: rc() : m_over_top(0) { PB_DS_ASSERT_VALID((*this)) } template rc<_Node, _Alloc>:: rc(const rc<_Node, _Alloc>& other) : m_over_top(0) { PB_DS_ASSERT_VALID((*this)) } template inline void rc<_Node, _Alloc>:: swap(rc<_Node, _Alloc>& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) const size_type over_top = std::max(m_over_top, other.m_over_top); for (size_type i = 0; i < over_top; ++i) std::swap(m_a_entries[i], other.m_a_entries[i]); std::swap(m_over_top, other.m_over_top); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } template inline void rc<_Node, _Alloc>:: push(entry p_nd) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(m_over_top < max_entries); m_a_entries[m_over_top++] = p_nd; PB_DS_ASSERT_VALID((*this)) } template inline void rc<_Node, _Alloc>:: pop() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); --m_over_top; PB_DS_ASSERT_VALID((*this)) } template inline typename rc<_Node, _Alloc>::node_pointer rc<_Node, _Alloc>:: top() const { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); return *(m_a_entries + m_over_top - 1); } template inline bool rc<_Node, _Alloc>:: empty() const { PB_DS_ASSERT_VALID((*this)) return m_over_top == 0; } template inline typename rc<_Node, _Alloc>::size_type rc<_Node, _Alloc>:: size() const { return m_over_top; } template void rc<_Node, _Alloc>:: clear() { PB_DS_ASSERT_VALID((*this)) m_over_top = 0; PB_DS_ASSERT_VALID((*this)) } template const typename rc<_Node, _Alloc>::const_iterator rc<_Node, _Alloc>:: begin() const { return& m_a_entries[0]; } template const typename rc<_Node, _Alloc>::const_iterator rc<_Node, _Alloc>:: end() const { return& m_a_entries[m_over_top]; } #ifdef _GLIBCXX_DEBUG template void rc<_Node, _Alloc>:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_over_top < max_entries); } #endif #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ template void rc<_Node, _Alloc>:: trace() const { std::cout << "rc" << std::endl; for (size_type i = 0; i < m_over_top; ++i) std::cerr << m_a_entries[i] << std::endl; std::cout << std::endl; } #endif } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/rc_binomial_heap_/split_join_fn_imps.hpp000064400000004562152526447520020077 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/split_join_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) make_binomial_heap(); other.make_binomial_heap(); base_type::split(pred, other); base_type::find_max(); other.find_max(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) make_binomial_heap(); other.make_binomial_heap(); base_type::join(other); base_type::find_max(); other.find_max(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } 8/ext/pb_ds/detail/types_traits.hpp000064400000023416152526447520013331 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/types_traits.hpp * Contains a traits class of types used by containers. */ #ifndef PB_DS_TYPES_TRAITS_HPP #define PB_DS_TYPES_TRAITS_HPP #include #include #include #include #include namespace __gnu_pbds { namespace detail { /** * @addtogroup traits Traits * @{ */ /// Primary template. template struct no_throw_copies { static const bool __simple = is_simple::value && is_simple::value; typedef integral_constant indicator; }; /// Specialization. template struct no_throw_copies { typedef integral_constant::value> indicator; }; /// Stored value. template struct stored_value { typedef _Tv value_type; value_type m_value; }; /// Stored hash. template struct stored_hash { typedef _Th hash_type; hash_type m_hash; }; /// Primary template for representation of stored data. /// Two types of data can be stored: value and hash. template struct stored_data : public stored_value<_Tv>, public stored_hash<_Th> { }; /// Specialization for representation of stored data of just value type. template struct stored_data<_Tv, null_type> : public stored_value<_Tv> { }; /// Primary template. template struct type_base; /** * Specialization of type_base for the case where the hash value * is not stored alongside each value. */ template struct type_base { public: typedef typename _Alloc::size_type size_type; private: typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef std::pair __value_type; typedef typename _Alloc::template rebind<__value_type> __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_ma::value_type mapped_type; typedef typename __rebind_ma::pointer mapped_pointer; typedef typename __rebind_ma::const_pointer mapped_const_pointer; typedef typename __rebind_ma::reference mapped_reference; typedef typename __rebind_ma::const_reference mapped_const_reference; typedef typename __rebind_va::value_type value_type; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef stored_data stored_data_type; }; /** * Specialization of type_base for the case where the hash value * is stored alongside each value. */ template struct type_base { public: typedef typename _Alloc::size_type size_type; private: typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef std::pair __value_type; typedef typename _Alloc::template rebind<__value_type> __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_ma::value_type mapped_type; typedef typename __rebind_ma::pointer mapped_pointer; typedef typename __rebind_ma::const_pointer mapped_const_pointer; typedef typename __rebind_ma::reference mapped_reference; typedef typename __rebind_ma::const_reference mapped_const_reference; typedef typename __rebind_va::value_type value_type; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef stored_data stored_data_type; }; /** * Specialization of type_base for the case where the hash value * is not stored alongside each value. */ template struct type_base { public: typedef typename _Alloc::size_type size_type; typedef Key value_type; private: typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef typename _Alloc::template rebind __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_ma::value_type mapped_type; typedef typename __rebind_ma::pointer mapped_pointer; typedef typename __rebind_ma::const_pointer mapped_const_pointer; typedef typename __rebind_ma::reference mapped_reference; typedef typename __rebind_ma::const_reference mapped_const_reference; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef stored_data stored_data_type; static null_type s_null_type; }; template null_type type_base::s_null_type; /** * Specialization of type_base for the case where the hash value * is stored alongside each value. */ template struct type_base { public: typedef typename _Alloc::size_type size_type; typedef Key value_type; private: typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef typename _Alloc::template rebind __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_ma::value_type mapped_type; typedef typename __rebind_ma::pointer mapped_pointer; typedef typename __rebind_ma::const_pointer mapped_const_pointer; typedef typename __rebind_ma::reference mapped_reference; typedef typename __rebind_ma::const_reference mapped_const_reference; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef stored_data stored_data_type; static null_type s_null_type; }; template null_type type_base::s_null_type; /// Type base dispatch. template struct type_dispatch { typedef type_base type; }; /// Traits for abstract types. template struct types_traits : public type_dispatch::type { private: typedef no_throw_copies __nothrowcopy; typedef typename _Alloc::template rebind::other __rebind_a; public: typedef typename _Alloc::size_type size_type; typedef typename __rebind_a::value_type key_type; typedef typename __rebind_a::pointer key_pointer; typedef typename __rebind_a::const_pointer key_const_pointer; typedef typename __rebind_a::reference key_reference; typedef typename __rebind_a::const_reference key_const_reference; typedef std::pair comp_hash; typedef integral_constant store_extra; typedef typename __nothrowcopy::indicator no_throw_indicator; store_extra m_store_extra_indicator; no_throw_indicator m_no_throw_copies_indicator; }; //@} } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/tree_trace_base.hpp000064400000012016152526447520013700 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/tree_trace_base.hpp * Contains tree-related policies. */ #ifndef PB_DS_TREE_TRACE_BASE_HPP #define PB_DS_TREE_TRACE_BASE_HPP #ifdef PB_DS_TREE_TRACE #include #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_TREE_TRACE #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ tree_trace_base #define PB_DS_TRACE_BASE \ branch_policy /// Tracing base class. template class tree_trace_base : private PB_DS_TRACE_BASE { public: void trace() const; private: typedef PB_DS_TRACE_BASE base_type; typedef Node_CItr node_const_iterator; typedef typename _Alloc::size_type size_type; void trace_node(node_const_iterator, size_type) const; virtual bool empty() const = 0; virtual node_const_iterator node_begin() const = 0; virtual node_const_iterator node_end() const = 0; static void print_node_pointer(Node_CItr, integral_constant); static void print_node_pointer(Node_CItr, integral_constant); template static void trace_it_metadata(Node_CItr, type_to_type); static void trace_it_metadata(Node_CItr, type_to_type); }; PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { if (empty()) return; trace_node(node_begin(), 0); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node(node_const_iterator nd_it, size_type level) const { if (nd_it.get_r_child() != node_end()) trace_node(nd_it.get_r_child(), level + 1); for (size_type i = 0; i < level; ++i) std::cerr << ' '; print_node_pointer(nd_it, integral_constant()); std::cerr << base_type::extract_key(*(*nd_it)); typedef type_to_type m_type_ind_t; trace_it_metadata(nd_it, m_type_ind_t()); std::cerr << std::endl; if (nd_it.get_l_child() != node_end()) trace_node(nd_it.get_l_child(), level + 1); } PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: trace_it_metadata(Node_CItr nd_it, type_to_type) { const unsigned long ul = static_cast(nd_it.get_metadata()); std::cerr << " (" << ul << ") "; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_it_metadata(Node_CItr, type_to_type) { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: print_node_pointer(Node_CItr nd_it, integral_constant) { std::cerr << nd_it.m_p_nd << " "; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: print_node_pointer(Node_CItr nd_it, integral_constant) { std::cerr << *nd_it << " "; } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_TRACE_BASE #endif // #ifdef PB_DS_TREE_TRACE } // namespace detail } // namespace __gnu_pbds #endif // #ifdef PB_DS_TREE_TRACE #endif // #ifndef PB_DS_TREE_TRACE_BASE_HPP 8/ext/pb_ds/detail/standard_policies.hpp000064400000011647152526447520014271 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/standard_policies.hpp * Contains standard policies for containers. */ #ifndef PB_DS_STANDARD_POLICIES_HPP #define PB_DS_STANDARD_POLICIES_HPP #include #include #include #include #include #include #include #include namespace __gnu_pbds { namespace detail { /// Primary template, default_hash_fn. template struct default_hash_fn { /// Dispatched type. typedef std::tr1::hash type; }; /// Primary template, default_eq_fn. template struct default_eq_fn { /// Dispatched type. typedef std::equal_to type; }; /// Enumeration for default behavior of stored hash data. enum { default_store_hash = false }; /// Primary template, default_comb_hash_fn. struct default_comb_hash_fn { /// Dispatched type. typedef direct_mask_range_hashing<> type; }; /// Primary template, default_resize_policy. template struct default_resize_policy { private: typedef typename Comb_Hash_Fn::size_type size_type; typedef direct_mask_range_hashing default_fn; typedef is_same same_type; typedef hash_exponential_size_policy iftrue; typedef hash_prime_size_policy iffalse; typedef __conditional_type cond_type; typedef typename cond_type::__type size_policy_type; typedef hash_load_check_resize_trigger trigger; public: /// Dispatched type. typedef hash_standard_resize_policy type; }; /// Default update policy. struct default_update_policy { /// Dispatched type. typedef lu_move_to_front_policy<> type; }; /// Primary template, default_probe_fn. template struct default_probe_fn { private: typedef typename Comb_Probe_Fn::size_type size_type; typedef direct_mask_range_hashing default_fn; typedef is_same same_type; typedef linear_probe_fn iftrue; typedef quadratic_probe_fn iffalse; typedef __conditional_type cond_type; public: /// Dispatched type. typedef typename cond_type::__type type; }; /// Primary template, default_trie_access_traits. template struct default_trie_access_traits; #define __dtrie_alloc std::allocator #define __dtrie_string std::basic_string /// Partial specialization, default_trie_access_traits. template struct default_trie_access_traits<__dtrie_string> { private: typedef __dtrie_string string_type; public: /// Dispatched type. typedef trie_string_access_traits type; }; #undef __dtrie_alloc #undef __dtrie_string } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_STANDARD_POLICIES_HPP 8/ext/pb_ds/detail/rb_tree_map_/node.hpp000064400000007436152526447520014146 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/node.hpp * Contains an implementation for rb_tree_. */ #ifndef PB_DS_RB_TREE_NODE_HPP #define PB_DS_RB_TREE_NODE_HPP #include namespace __gnu_pbds { namespace detail { /// Node for Red-Black trees. template struct rb_tree_node_ { public: typedef Value_Type value_type; typedef Metadata metadata_type; typedef typename _Alloc::template rebind< rb_tree_node_< Value_Type, Metadata, _Alloc> >::other::pointer node_pointer; typedef typename _Alloc::template rebind< metadata_type>::other::reference metadata_reference; typedef typename _Alloc::template rebind< metadata_type>::other::const_reference metadata_const_reference; bool special() const { return m_red; } metadata_const_reference get_metadata() const { return m_metadata; } metadata_reference get_metadata() { return m_metadata; } #ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ void trace() const { std::cout << PB_DS_V2F(m_value) <<(m_red? " " : " ") << "(" << m_metadata << ")"; } #endif node_pointer m_p_left; node_pointer m_p_right; node_pointer m_p_parent; value_type m_value; bool m_red; metadata_type m_metadata; }; template struct rb_tree_node_ { public: typedef Value_Type value_type; typedef null_type metadata_type; typedef typename _Alloc::template rebind< rb_tree_node_< Value_Type, null_type, _Alloc> >::other::pointer node_pointer; bool special() const { return m_red; } #ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ void trace() const { std::cout << PB_DS_V2F(m_value) <<(m_red? " " : " "); } #endif node_pointer m_p_left; node_pointer m_p_right; node_pointer m_p_parent; value_type m_value; bool m_red; }; } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp000064400000005337152526447520021760 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/constructors_destructor_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_RB_TREE_NAME() { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_RB_TREE_NAME(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_RB_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : base_type(r_cmp_fn, r_node_update) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_RB_TREE_NAME(const PB_DS_CLASS_C_DEC& other) : base_type(other) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) base_type::swap(other); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { base_type::m_p_head->m_red = true; } 8/ext/pb_ds/detail/rb_tree_map_/info_fn_imps.hpp000064400000003461152526447520015661 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/info_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_effectively_black(const node_pointer p_nd) { return (p_nd == 0 || !p_nd->m_red); } 8/ext/pb_ds/detail/rb_tree_map_/find_fn_imps.hpp000064400000003247152526447520015650 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/find_fn_imps.hpp * Contains an implementation for rb_tree_. */ 8/ext/pb_ds/detail/rb_tree_map_/debug_fn_imps.hpp000064400000005311152526447520016010 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/debug_fn_imps.hpp * Contains an implementation for rb_tree_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: assert_node_consistent(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) return 1; const size_type l_height = assert_node_consistent(p_nd->m_p_left, __file, __line); const size_type r_height = assert_node_consistent(p_nd->m_p_right, __file, __line); if (p_nd->m_red) { PB_DS_DEBUG_VERIFY(is_effectively_black(p_nd->m_p_left)); PB_DS_DEBUG_VERIFY(is_effectively_black(p_nd->m_p_right)); } PB_DS_DEBUG_VERIFY(l_height == r_height); return (p_nd->m_red ? 0 : 1) + l_height; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(__file, __line); const node_pointer p_head = base_type::m_p_head; PB_DS_DEBUG_VERIFY(p_head->m_red); if (p_head->m_p_parent != 0) { PB_DS_DEBUG_VERIFY(!p_head->m_p_parent->m_red); assert_node_consistent(p_head->m_p_parent, __file, __line); } } #endif 8/ext/pb_ds/detail/rb_tree_map_/insert_fn_imps.hpp000064400000007433152526447520016235 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/insert_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert(const_reference r_value) { PB_DS_ASSERT_VALID((*this)) std::pair ins_pair = base_type::insert_leaf(r_value); if (ins_pair.second == true) { ins_pair.first.m_p_nd->m_red = true; PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) insert_fixup(ins_pair.first.m_p_nd); } PB_DS_ASSERT_VALID((*this)) return ins_pair; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_fixup(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_red == true); while (p_nd != base_type::m_p_head->m_p_parent && p_nd->m_p_parent->m_red) { if (p_nd->m_p_parent == p_nd->m_p_parent->m_p_parent->m_p_left) { node_pointer p_y = p_nd->m_p_parent->m_p_parent->m_p_right; if (p_y != 0 && p_y->m_red) { p_nd->m_p_parent->m_red = false; p_y->m_red = false; p_nd->m_p_parent->m_p_parent->m_red = true; p_nd = p_nd->m_p_parent->m_p_parent; } else { if (p_nd == p_nd->m_p_parent->m_p_right) { p_nd = p_nd->m_p_parent; base_type::rotate_left(p_nd); } p_nd->m_p_parent->m_red = false; p_nd->m_p_parent->m_p_parent->m_red = true; base_type::rotate_right(p_nd->m_p_parent->m_p_parent); } } else { node_pointer p_y = p_nd->m_p_parent->m_p_parent->m_p_left; if (p_y != 0 && p_y->m_red) { p_nd->m_p_parent->m_red = false; p_y->m_red = false; p_nd->m_p_parent->m_p_parent->m_red = true; p_nd = p_nd->m_p_parent->m_p_parent; } else { if (p_nd == p_nd->m_p_parent->m_p_left) { p_nd = p_nd->m_p_parent; base_type::rotate_right(p_nd); } p_nd->m_p_parent->m_red = false; p_nd->m_p_parent->m_p_parent->m_red = true; base_type::rotate_left(p_nd->m_p_parent->m_p_parent); } } } base_type::update_to_top(p_nd, (node_update* )this); base_type::m_p_head->m_p_parent->m_red = false; } 8/ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp000064400000017432152526447520014777 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/rb_tree_.hpp * Contains an implementation for Red Black trees. */ #include #include #include #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #ifdef PB_DS_DATA_TRUE_INDICATOR # define PB_DS_RB_TREE_NAME rb_tree_map # define PB_DS_RB_TREE_BASE_NAME bin_search_tree_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR # define PB_DS_RB_TREE_NAME rb_tree_set # define PB_DS_RB_TREE_BASE_NAME bin_search_tree_set #endif #define PB_DS_CLASS_C_DEC \ PB_DS_RB_TREE_NAME #define PB_DS_RB_TREE_BASE \ PB_DS_RB_TREE_BASE_NAME /** * @brief Red-Black tree. * @ingroup branch-detail * * This implementation uses an idea from the SGI STL (using a * @a header node which is needed for efficient iteration). */ template class PB_DS_RB_TREE_NAME : public PB_DS_RB_TREE_BASE { private: typedef PB_DS_RB_TREE_BASE base_type; typedef typename base_type::node_pointer node_pointer; public: typedef rb_tree_tag container_category; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename base_type::key_type key_type; typedef typename base_type::key_pointer key_pointer; typedef typename base_type::key_const_pointer key_const_pointer; typedef typename base_type::key_reference key_reference; typedef typename base_type::key_const_reference key_const_reference; typedef typename base_type::mapped_type mapped_type; typedef typename base_type::mapped_pointer mapped_pointer; typedef typename base_type::mapped_const_pointer mapped_const_pointer; typedef typename base_type::mapped_reference mapped_reference; typedef typename base_type::mapped_const_reference mapped_const_reference; typedef typename base_type::value_type value_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator point_const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::reverse_iterator reverse_iterator; typedef typename base_type::const_reverse_iterator const_reverse_iterator; typedef typename base_type::node_update node_update; PB_DS_RB_TREE_NAME(); PB_DS_RB_TREE_NAME(const Cmp_Fn&); PB_DS_RB_TREE_NAME(const Cmp_Fn&, const node_update&); PB_DS_RB_TREE_NAME(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); template void copy_from_range(It, It); inline std::pair insert(const_reference); inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) std::pair ins_pair = base_type::insert_leaf(value_type(r_key, mapped_type())); if (ins_pair.second == true) { ins_pair.first.m_p_nd->m_red = true; _GLIBCXX_DEBUG_ONLY(this->structure_only_assert_valid(__FILE__, __LINE__);) insert_fixup(ins_pair.first.m_p_nd); } _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return ins_pair.first.m_p_nd->m_value.second; #else insert(r_key); return base_type::s_null_type; #endif } inline bool erase(key_const_reference); inline iterator erase(iterator); inline reverse_iterator erase(reverse_iterator); template inline size_type erase_if(Pred); void join(PB_DS_CLASS_C_DEC&); void split(key_const_reference, PB_DS_CLASS_C_DEC&); private: #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; size_type assert_node_consistent(const node_pointer, const char*, int) const; #endif inline static bool is_effectively_black(const node_pointer); void initialize(); void insert_fixup(node_pointer); void erase_node(node_pointer); void remove_node(node_pointer); void remove_fixup(node_pointer, node_pointer); void split_imp(node_pointer, PB_DS_CLASS_C_DEC&); inline node_pointer split_min(); std::pair split_min_imp(); void join_imp(node_pointer, node_pointer); std::pair find_join_pos_right(node_pointer, size_type, size_type); std::pair find_join_pos_left(node_pointer, size_type, size_type); inline size_type black_height(node_pointer); void split_at_node(node_pointer, PB_DS_CLASS_C_DEC&); }; #define PB_DS_STRUCT_ONLY_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.structure_only_assert_valid(__FILE__, __LINE__);) #include #include #include #include #include #include #undef PB_DS_STRUCT_ONLY_ASSERT_VALID #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_RB_TREE_NAME #undef PB_DS_RB_TREE_BASE_NAME #undef PB_DS_RB_TREE_BASE } // namespace detail } // namespace __gnu_pbds 8/ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp000064400000015613152526447520016027 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/erase_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { point_iterator it = this->find(r_key); if (it == base_type::end()) return false; erase(it); return true; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: erase(iterator it) { PB_DS_ASSERT_VALID((*this)) if (it == base_type::end()) return it; iterator ret_it = it; ++ret_it; erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ret_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: erase(reverse_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it.m_p_nd == base_type::m_p_head) return it; reverse_iterator ret_it = it; ++ret_it; erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ret_it; } PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) size_type num_ersd = 0; iterator it = base_type::begin(); while (it != base_type::end()) { if (pred(*it)) { ++num_ersd; it = erase(it); } else ++it; } PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_node(node_pointer p_nd) { remove_node(p_nd); base_type::actual_erase_node(p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_node(node_pointer p_z) { this->update_min_max_for_erased_node(p_z); node_pointer p_y = p_z; node_pointer p_x = 0; node_pointer p_new_x_parent = 0; if (p_y->m_p_left == 0) p_x = p_y->m_p_right; else if (p_y->m_p_right == 0) p_x = p_y->m_p_left; else { p_y = p_y->m_p_right; while (p_y->m_p_left != 0) p_y = p_y->m_p_left; p_x = p_y->m_p_right; } if (p_y == p_z) { p_new_x_parent = p_y->m_p_parent; if (p_x != 0) p_x->m_p_parent = p_y->m_p_parent; if (base_type::m_p_head->m_p_parent == p_z) base_type::m_p_head->m_p_parent = p_x; else if (p_z->m_p_parent->m_p_left == p_z) { p_y->m_p_left = p_z->m_p_parent; p_z->m_p_parent->m_p_left = p_x; } else { p_y->m_p_left = 0; p_z->m_p_parent->m_p_right = p_x; } } else { p_z->m_p_left->m_p_parent = p_y; p_y->m_p_left = p_z->m_p_left; if (p_y != p_z->m_p_right) { p_new_x_parent = p_y->m_p_parent; if (p_x != 0) p_x->m_p_parent = p_y->m_p_parent; p_y->m_p_parent->m_p_left = p_x; p_y->m_p_right = p_z->m_p_right; p_z->m_p_right->m_p_parent = p_y; } else p_new_x_parent = p_y; if (base_type::m_p_head->m_p_parent == p_z) base_type::m_p_head->m_p_parent = p_y; else if (p_z->m_p_parent->m_p_left == p_z) p_z->m_p_parent->m_p_left = p_y; else p_z->m_p_parent->m_p_right = p_y; p_y->m_p_parent = p_z->m_p_parent; std::swap(p_y->m_red, p_z->m_red); p_y = p_z; } this->update_to_top(p_new_x_parent, (node_update* )this); if (p_y->m_red) return; remove_fixup(p_x, p_new_x_parent); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_fixup(node_pointer p_x, node_pointer p_new_x_parent) { _GLIBCXX_DEBUG_ASSERT(p_x == 0 || p_x->m_p_parent == p_new_x_parent); while (p_x != base_type::m_p_head->m_p_parent && is_effectively_black(p_x)) if (p_x == p_new_x_parent->m_p_left) { node_pointer p_w = p_new_x_parent->m_p_right; if (p_w->m_red) { p_w->m_red = false; p_new_x_parent->m_red = true; base_type::rotate_left(p_new_x_parent); p_w = p_new_x_parent->m_p_right; } if (is_effectively_black(p_w->m_p_left) && is_effectively_black(p_w->m_p_right)) { p_w->m_red = true; p_x = p_new_x_parent; p_new_x_parent = p_new_x_parent->m_p_parent; } else { if (is_effectively_black(p_w->m_p_right)) { if (p_w->m_p_left != 0) p_w->m_p_left->m_red = false; p_w->m_red = true; base_type::rotate_right(p_w); p_w = p_new_x_parent->m_p_right; } p_w->m_red = p_new_x_parent->m_red; p_new_x_parent->m_red = false; if (p_w->m_p_right != 0) p_w->m_p_right->m_red = false; base_type::rotate_left(p_new_x_parent); this->update_to_top(p_new_x_parent, (node_update* )this); break; } } else { node_pointer p_w = p_new_x_parent->m_p_left; if (p_w->m_red == true) { p_w->m_red = false; p_new_x_parent->m_red = true; base_type::rotate_right(p_new_x_parent); p_w = p_new_x_parent->m_p_left; } if (is_effectively_black(p_w->m_p_right) && is_effectively_black(p_w->m_p_left)) { p_w->m_red = true; p_x = p_new_x_parent; p_new_x_parent = p_new_x_parent->m_p_parent; } else { if (is_effectively_black(p_w->m_p_left)) { if (p_w->m_p_right != 0) p_w->m_p_right->m_red = false; p_w->m_red = true; base_type::rotate_left(p_w); p_w = p_new_x_parent->m_p_left; } p_w->m_red = p_new_x_parent->m_red; p_new_x_parent->m_red = false; if (p_w->m_p_left != 0) p_w->m_p_left->m_red = false; base_type::rotate_right(p_new_x_parent); this->update_to_top(p_new_x_parent, (node_update* )this); break; } } if (p_x != 0) p_x->m_red = false; } 8/ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hpp000064400000017265152526447520017107 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/split_join_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (base_type::join_prep(other) == false) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } const node_pointer p_x = other.split_min(); join_imp(p_x, other.m_p_head->m_p_parent); base_type::join_finish(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join_imp(node_pointer p_x, node_pointer p_r) { _GLIBCXX_DEBUG_ASSERT(p_x != 0); if (p_r != 0) p_r->m_red = false; const size_type h = black_height(base_type::m_p_head->m_p_parent); const size_type other_h = black_height(p_r); node_pointer p_x_l; node_pointer p_x_r; std::pair join_pos; const bool right_join = h >= other_h; if (right_join) { join_pos = find_join_pos_right(base_type::m_p_head->m_p_parent, h, other_h); p_x_l = join_pos.first; p_x_r = p_r; } else { p_x_l = base_type::m_p_head->m_p_parent; base_type::m_p_head->m_p_parent = p_r; if (p_r != 0) p_r->m_p_parent = base_type::m_p_head; join_pos = find_join_pos_left(base_type::m_p_head->m_p_parent, h, other_h); p_x_r = join_pos.first; } node_pointer p_parent = join_pos.second; if (p_parent == base_type::m_p_head) { base_type::m_p_head->m_p_parent = p_x; p_x->m_p_parent = base_type::m_p_head; } else { p_x->m_p_parent = p_parent; if (right_join) p_x->m_p_parent->m_p_right = p_x; else p_x->m_p_parent->m_p_left = p_x; } p_x->m_p_left = p_x_l; if (p_x_l != 0) p_x_l->m_p_parent = p_x; p_x->m_p_right = p_x_r; if (p_x_r != 0) p_x_r->m_p_parent = p_x; p_x->m_red = true; base_type::initialize_min_max(); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) base_type::update_to_top(p_x, (node_update* )this); insert_fixup(p_x); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: split_min() { node_pointer p_min = base_type::m_p_head->m_p_left; #ifdef _GLIBCXX_DEBUG const node_pointer p_head = base_type::m_p_head; _GLIBCXX_DEBUG_ASSERT(p_min != p_head); #endif remove_node(p_min); return p_min; } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::node_pointer, typename PB_DS_CLASS_C_DEC::node_pointer> PB_DS_CLASS_C_DEC:: find_join_pos_right(node_pointer p_l, size_type h_l, size_type h_r) { _GLIBCXX_DEBUG_ASSERT(h_l >= h_r); if (base_type::m_p_head->m_p_parent == 0) return (std::make_pair((node_pointer)0, base_type::m_p_head)); node_pointer p_l_parent = base_type::m_p_head; while (h_l > h_r) { if (p_l->m_red == false) { _GLIBCXX_DEBUG_ASSERT(h_l > 0); --h_l; } p_l_parent = p_l; p_l = p_l->m_p_right; } if (!is_effectively_black(p_l)) { p_l_parent = p_l; p_l = p_l->m_p_right; } _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_l)); _GLIBCXX_DEBUG_ASSERT(black_height(p_l) == h_r); _GLIBCXX_DEBUG_ASSERT(p_l == 0 || p_l->m_p_parent == p_l_parent); return std::make_pair(p_l, p_l_parent); } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::node_pointer, typename PB_DS_CLASS_C_DEC::node_pointer> PB_DS_CLASS_C_DEC:: find_join_pos_left(node_pointer p_r, size_type h_l, size_type h_r) { _GLIBCXX_DEBUG_ASSERT(h_r > h_l); if (base_type::m_p_head->m_p_parent == 0) return (std::make_pair((node_pointer)0, base_type::m_p_head)); node_pointer p_r_parent = base_type::m_p_head; while (h_r > h_l) { if (p_r->m_red == false) { _GLIBCXX_DEBUG_ASSERT(h_r > 0); --h_r; } p_r_parent = p_r; p_r = p_r->m_p_left; } if (!is_effectively_black(p_r)) { p_r_parent = p_r; p_r = p_r->m_p_left; } _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_r)); _GLIBCXX_DEBUG_ASSERT(black_height(p_r) == h_l); _GLIBCXX_DEBUG_ASSERT(p_r == 0 || p_r->m_p_parent == p_r_parent); return std::make_pair(p_r, p_r_parent); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: black_height(node_pointer p_nd) { size_type h = 1; while (p_nd != 0) { if (p_nd->m_red == false) ++h; p_nd = p_nd->m_p_left; } return h; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (base_type::split_prep(r_key, other) == false) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) node_pointer p_nd = this->upper_bound(r_key).m_p_nd; do { node_pointer p_next_nd = p_nd->m_p_parent; if (Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) split_at_node(p_nd, other); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) p_nd = p_next_nd; } while (p_nd != base_type::m_p_head); base_type::split_finish(other); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split_at_node(node_pointer p_nd, PB_DS_CLASS_C_DEC& other) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); node_pointer p_l = p_nd->m_p_left; node_pointer p_r = p_nd->m_p_right; node_pointer p_parent = p_nd->m_p_parent; if (p_parent == base_type::m_p_head) { base_type::m_p_head->m_p_parent = p_l; if (p_l != 0) { p_l->m_p_parent = base_type::m_p_head; p_l->m_red = false; } } else { if (p_parent->m_p_left == p_nd) p_parent->m_p_left = p_l; else p_parent->m_p_right = p_l; if (p_l != 0) p_l->m_p_parent = p_parent; this->update_to_top(p_parent, (node_update* )this); if (!p_nd->m_red) remove_fixup(p_l, p_parent); } base_type::initialize_min_max(); other.join_imp(p_nd, p_r); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) } 8/ext/pb_ds/detail/rb_tree_map_/traits.hpp000064400000006323152526447520014521 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/traits.hpp * Contains an implementation for rb_tree_. */ #ifndef PB_DS_RB_TREE_NODE_AND_IT_TRAITS_HPP #define PB_DS_RB_TREE_NODE_AND_IT_TRAITS_HPP #include namespace __gnu_pbds { namespace detail { /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct tree_traits : public bin_search_tree_traits< Key, Mapped, Cmp_Fn, Node_Update, rb_tree_node_< typename types_traits::value_type, typename tree_node_metadata_dispatch::type, _Alloc>, _Alloc> { }; /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct tree_traits : public bin_search_tree_traits< Key, null_type, Cmp_Fn, Node_Update, rb_tree_node_< typename types_traits::value_type, typename tree_node_metadata_dispatch::type, _Alloc>, _Alloc> { }; } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/binary_heap_/const_iterator.hpp000064400000010362152526447520016252 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/const_iterator.hpp * Contains an iterator class returned by the table's const find and insert * methods. */ #ifndef PB_DS_BINARY_HEAP_CONST_ITERATOR_HPP #define PB_DS_BINARY_HEAP_CONST_ITERATOR_HPP #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_BIN_HEAP_CIT_BASE \ binary_heap_point_const_iterator_ /// Const point-type iterator. template class binary_heap_const_iterator_ : public PB_DS_BIN_HEAP_CIT_BASE { private: typedef PB_DS_BIN_HEAP_CIT_BASE base_type; typedef typename base_type::entry_pointer entry_pointer; public: /// Category. typedef std::forward_iterator_tag iterator_category; /// Difference type. typedef typename _Alloc::difference_type difference_type; /// Iterator's value type. typedef typename base_type::value_type value_type; /// Iterator's pointer type. typedef typename base_type::pointer pointer; /// Iterator's const pointer type. typedef typename base_type::const_pointer const_pointer; /// Iterator's reference type. typedef typename base_type::reference reference; /// Iterator's const reference type. typedef typename base_type::const_reference const_reference; inline binary_heap_const_iterator_(entry_pointer p_e) : base_type(p_e) { } /// Default constructor. inline binary_heap_const_iterator_() { } /// Copy constructor. inline binary_heap_const_iterator_(const binary_heap_const_iterator_& other) : base_type(other) { } /// Compares content to a different iterator object. inline bool operator==(const binary_heap_const_iterator_& other) const { return base_type::m_p_e == other.m_p_e; } /// Compares content (negatively) to a different iterator object. inline bool operator!=(const binary_heap_const_iterator_& other) const { return base_type::m_p_e != other.m_p_e; } inline binary_heap_const_iterator_& operator++() { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_e != 0); inc(); return *this; } inline binary_heap_const_iterator_ operator++(int) { binary_heap_const_iterator_ ret_it(base_type::m_p_e); operator++(); return ret_it; } private: void inc() { ++base_type::m_p_e; } }; #undef PB_DS_BIN_HEAP_CIT_BASE } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/binary_heap_/entry_pred.hpp000064400000005341152526447520015367 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/entry_pred.hpp * Contains an implementation class for a binary_heap. */ #ifndef PB_DS_BINARY_HEAP_ENTRY_PRED_HPP #define PB_DS_BINARY_HEAP_ENTRY_PRED_HPP namespace __gnu_pbds { namespace detail { /// Entry predicate primary class template. template struct entry_pred; /// Specialization, true. template struct entry_pred<_VTp, Pred, _Alloc, true> { typedef Pred type; }; /// Specialization, false. template struct entry_pred<_VTp, Pred, _Alloc, false> { private: typedef typename _Alloc::template rebind<_VTp> __rebind_v; public: typedef typename __rebind_v::other::const_pointer entry; struct type : public Pred { inline type() { } inline type(const Pred& other) : Pred(other) { } inline bool operator()(entry p_v) const { return Pred::operator()(*p_v); } }; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BINARY_HEAP_ENTRY_PRED_HPP 8/ext/pb_ds/detail/binary_heap_/trace_fn_imps.hpp000064400000004617152526447520016032 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/trace_fn_imps.hpp * Contains an implementation class for a binary_heap. */ #ifdef PB_DS_BINARY_HEAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << this << std::endl; std::cerr << m_a_entries << std::endl; for (size_type i = 0; i < m_size; ++i) trace_entry(m_a_entries[i], s_no_throw_copies_ind); std::cerr << std::endl; std::cerr << "size = " << m_size << " " << "actual_size = " << m_actual_size << std::endl; resize_policy::trace(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_entry(const entry& r_e, false_type) const { std::cout << r_e << " " <<* r_e << std::endl; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_entry(const entry& r_e, true_type) const { std::cout << r_e << std::endl; } #endif // #ifdef PB_DS_BINARY_HEAP_TRACE_ 8/ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hpp000064400000003556152526447520017555 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/policy_access_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() { return (*this); } PB_DS_CLASS_T_DEC const Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() const { return (*this); } 8/ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hpp000064400000010135152526447520021752 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation class for binary_heap_. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_allocator PB_DS_CLASS_C_DEC::s_entry_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::value_allocator PB_DS_CLASS_C_DEC::s_value_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::no_throw_copies_t PB_DS_CLASS_C_DEC::s_no_throw_copies_ind; PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) { insert_value(*first_it, s_no_throw_copies_ind); ++first_it; } make_heap(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binary_heap() : m_size(0), m_actual_size(resize_policy::min_size), m_a_entries(s_entry_allocator.allocate(m_actual_size)) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binary_heap(const Cmp_Fn& r_cmp_fn) : entry_cmp(r_cmp_fn), m_size(0), m_actual_size(resize_policy::min_size), m_a_entries(s_entry_allocator.allocate(m_actual_size)) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binary_heap(const PB_DS_CLASS_C_DEC& other) : entry_cmp(other), resize_policy(other), m_size(0), m_actual_size(other.m_actual_size), m_a_entries(s_entry_allocator.allocate(m_actual_size)) { PB_DS_ASSERT_VALID(other) _GLIBCXX_DEBUG_ASSERT(m_a_entries != other.m_a_entries); __try { copy_from_range(other.begin(), other.end()); } __catch(...) { for (size_type i = 0; i < m_size; ++i) erase_at(m_a_entries, i, s_no_throw_copies_ind); s_entry_allocator.deallocate(m_a_entries, m_actual_size); __throw_exception_again; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) _GLIBCXX_DEBUG_ASSERT(m_a_entries != other.m_a_entries); value_swap(other); std::swap((entry_cmp&)(*this), (entry_cmp&)other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_a_entries, other.m_a_entries); std::swap(m_size, other.m_size); std::swap(m_actual_size, other.m_actual_size); static_cast(this)->swap(other); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~binary_heap() { for (size_type i = 0; i < m_size; ++i) erase_at(m_a_entries, i, s_no_throw_copies_ind); s_entry_allocator.deallocate(m_a_entries, m_actual_size); } 8/ext/pb_ds/detail/binary_heap_/point_const_iterator.hpp000064400000010537152526447520017467 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/point_const_iterator.hpp * Contains an iterator class returned by the table's const find and insert * methods. */ #ifndef PB_DS_BINARY_HEAP_CONST_FIND_ITERATOR_HPP #define PB_DS_BINARY_HEAP_CONST_FIND_ITERATOR_HPP #include #include namespace __gnu_pbds { namespace detail { /// Const point-type iterator. template class binary_heap_point_const_iterator_ { protected: typedef typename _Alloc::template rebind::other::pointer entry_pointer; public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef Value_Type value_type; /// Iterator's pointer type. typedef typename _Alloc::template rebind::other::pointer pointer; /// Iterator's const pointer type. typedef typename _Alloc::template rebind::other::const_pointer const_pointer; /// Iterator's reference type. typedef typename _Alloc::template rebind::other::reference reference; /// Iterator's const reference type. typedef typename _Alloc::template rebind::other::const_reference const_reference; inline binary_heap_point_const_iterator_(entry_pointer p_e) : m_p_e(p_e) { } /// Default constructor. inline binary_heap_point_const_iterator_() : m_p_e(0) { } /// Copy constructor. inline binary_heap_point_const_iterator_(const binary_heap_point_const_iterator_& other) : m_p_e(other.m_p_e) { } /// Access. inline const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_e != 0); return to_ptr(integral_constant()); } /// Access. inline const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_e != 0); return *to_ptr(integral_constant()); } /// Compares content to a different iterator object. inline bool operator==(const binary_heap_point_const_iterator_& other) const { return m_p_e == other.m_p_e; } /// Compares content (negatively) to a different iterator object. inline bool operator!=(const binary_heap_point_const_iterator_& other) const { return m_p_e != other.m_p_e; } private: inline const_pointer to_ptr(true_type) const { return m_p_e; } inline const_pointer to_ptr(false_type) const { return *m_p_e; } public: entry_pointer m_p_e; }; } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp000064400000004016152526447520015660 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/info_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return m_size == 0; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_size; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_entry_allocator.max_size(); } 8/ext/pb_ds/detail/binary_heap_/entry_cmp.hpp000064400000005404152526447520015214 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/entry_cmp.hpp * Contains an implementation class for a binary_heap. */ #ifndef PB_DS_BINARY_HEAP_ENTRY_CMP_HPP #define PB_DS_BINARY_HEAP_ENTRY_CMP_HPP namespace __gnu_pbds { namespace detail { /// Entry compare, primary template. template struct entry_cmp; /// Specialization, true. template struct entry_cmp<_VTp, Cmp_Fn, _Alloc, true> { /// Compare. typedef Cmp_Fn type; }; /// Specialization, false. template struct entry_cmp<_VTp, Cmp_Fn, _Alloc, false> { private: typedef typename _Alloc::template rebind<_VTp> __rebind_v; public: typedef typename __rebind_v::other::const_pointer entry; /// Compare plus entry. struct type : public Cmp_Fn { type() { } type(const Cmp_Fn& other) : Cmp_Fn(other) { } bool operator()(entry lhs, entry rhs) const { return Cmp_Fn::operator()(*lhs, *rhs); } }; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BINARY_HEAP_ENTRY_CMP_HPP 8/ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp000064400000005045152526447520015650 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/find_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top() const { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); return top_imp(s_no_throw_copies_ind); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top_imp(true_type) const { return *m_a_entries; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top_imp(false_type) const { return **m_a_entries; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: left_child(size_type i) { return i * 2 + 1; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: right_child(size_type i) { return i * 2 + 2; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: parent(size_type i) { return (i - 1) / 2; } 8/ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hpp000064400000004336152526447520016746 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/iterators_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { return iterator(m_a_entries); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { return const_iterator(m_a_entries); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return iterator(m_a_entries + m_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return const_iterator(m_a_entries + m_size); } 8/ext/pb_ds/detail/binary_heap_/debug_fn_imps.hpp000064400000004755152526447520016025 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/debug_fn_imps.hpp * Contains an implementation class for a binary_heap. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { #ifdef PB_DS_REGRESSION s_entry_allocator.check_allocated(m_a_entries, m_actual_size); #endif resize_policy::assert_valid(__file, __line); PB_DS_DEBUG_VERIFY(m_size <= m_actual_size); for (size_type i = 0; i < m_size; ++i) { #ifdef PB_DS_REGRESSION s_value_allocator.check_allocated(m_a_entries[i], 1); #endif if (left_child(i) < m_size) PB_DS_DEBUG_VERIFY(!entry_cmp::operator()(m_a_entries[i], m_a_entries[left_child(i)])); PB_DS_DEBUG_VERIFY(parent(left_child(i)) == i); if (right_child(i) < m_size) PB_DS_DEBUG_VERIFY(!entry_cmp::operator()(m_a_entries[i], m_a_entries[right_child(i)])); PB_DS_DEBUG_VERIFY(parent(right_child(i)) == i); } } #endif 8/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp000064400000011562152526447520016235 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/insert_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) insert_value(r_val, s_no_throw_copies_ind); push_heap(); PB_DS_ASSERT_VALID((*this)) return point_iterator(m_a_entries); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_value(value_type val, true_type) { resize_for_insert_if_needed(); m_a_entries[m_size++] = val; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_value(const_reference r_val, false_type) { resize_for_insert_if_needed(); pointer p_new = s_value_allocator.allocate(1); cond_dealtor_t cond(p_new); new (p_new) value_type(r_val); cond.set_no_action(); m_a_entries[m_size++] = p_new; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: resize_for_insert_if_needed() { if (!resize_policy::resize_needed_for_grow(m_size)) { _GLIBCXX_DEBUG_ASSERT(m_size < m_actual_size); return; } const size_type new_size = resize_policy::get_new_size_for_grow(); entry_pointer new_entries = s_entry_allocator.allocate(new_size); resize_policy::notify_grow_resize(); std::copy(m_a_entries, m_a_entries + m_size, new_entries); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_actual_size = new_size; m_a_entries = new_entries; make_heap(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID((*this)) swap_value_imp(it.m_p_e, r_new_val, s_no_throw_copies_ind); fix(it.m_p_e); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: fix(entry_pointer p_e) { size_type i = p_e - m_a_entries; if (i > 0 && entry_cmp::operator()(m_a_entries[parent(i)], m_a_entries[i])) { size_type parent_i = parent(i); while (i > 0 && entry_cmp::operator()(m_a_entries[parent_i], m_a_entries[i])) { std::swap(m_a_entries[i], m_a_entries[parent_i]); i = parent_i; parent_i = parent(i); } PB_DS_ASSERT_VALID((*this)) return; } while (i < m_size) { const size_type lchild_i = left_child(i); const size_type rchild_i = right_child(i); _GLIBCXX_DEBUG_ASSERT(rchild_i > lchild_i); const bool smaller_than_lchild = lchild_i < m_size && entry_cmp::operator()(m_a_entries[i], m_a_entries[lchild_i]); const bool smaller_than_rchild = rchild_i < m_size && entry_cmp::operator()(m_a_entries[i], m_a_entries[rchild_i]); const bool swap_with_rchild = smaller_than_rchild && (!smaller_than_lchild || entry_cmp::operator()(m_a_entries[lchild_i], m_a_entries[rchild_i])); const bool swap_with_lchild = !swap_with_rchild && smaller_than_lchild; if (swap_with_lchild) { std::swap(m_a_entries[i], m_a_entries[lchild_i]); i = lchild_i; } else if (swap_with_rchild) { std::swap(m_a_entries[i], m_a_entries[rchild_i]); i = rchild_i; } else i = m_size; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap_value_imp(entry_pointer p_e, value_type new_val, true_type) { *p_e = new_val; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap_value_imp(entry_pointer p_e, const_reference r_new_val, false_type) { value_type tmp(r_new_val); (*p_e)->swap(tmp); } 8/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp000064400000012600152526447520016022 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/erase_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { for (size_type i = 0; i < m_size; ++i) erase_at(m_a_entries, i, s_no_throw_copies_ind); __try { const size_type new_size = resize_policy::get_new_size_for_arbitrary(0); entry_pointer new_entries = s_entry_allocator.allocate(new_size); resize_policy::notify_arbitrary(new_size); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_actual_size = new_size; m_a_entries = new_entries; } __catch(...) { } m_size = 0; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_at(entry_pointer a_entries, size_type i, false_type) { a_entries[i]->~value_type(); s_value_allocator.deallocate(a_entries[i], 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_at(entry_pointer, size_type, true_type) { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: pop() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); pop_heap(); erase_at(m_a_entries, m_size - 1, s_no_throw_copies_ind); resize_for_erase_if_needed(); _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) typedef typename entry_pred::type pred_t; const size_type left = partition(pred_t(pred)); _GLIBCXX_DEBUG_ASSERT(m_size >= left); const size_type ersd = m_size - left; for (size_type i = left; i < m_size; ++i) erase_at(m_a_entries, i, s_no_throw_copies_ind); __try { const size_type new_size = resize_policy::get_new_size_for_arbitrary(left); entry_pointer new_entries = s_entry_allocator.allocate(new_size); std::copy(m_a_entries, m_a_entries + left, new_entries); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_actual_size = new_size; resize_policy::notify_arbitrary(m_actual_size); } __catch(...) { }; m_size = left; make_heap(); PB_DS_ASSERT_VALID((*this)) return ersd; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); const size_type fix_pos = it.m_p_e - m_a_entries; std::swap(*it.m_p_e, m_a_entries[m_size - 1]); erase_at(m_a_entries, m_size - 1, s_no_throw_copies_ind); resize_for_erase_if_needed(); _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ASSERT(fix_pos <= m_size); if (fix_pos != m_size) fix(m_a_entries + fix_pos); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: resize_for_erase_if_needed() { if (!resize_policy::resize_needed_for_shrink(m_size)) return; __try { const size_type new_size = resize_policy::get_new_size_for_shrink(); entry_pointer new_entries = s_entry_allocator.allocate(new_size); resize_policy::notify_shrink_resize(); _GLIBCXX_DEBUG_ASSERT(m_size > 0); std::copy(m_a_entries, m_a_entries + m_size - 1, new_entries); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_actual_size = new_size; m_a_entries = new_entries; } __catch(...) { } } PB_DS_CLASS_T_DEC template typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: partition(Pred pred) { size_type left = 0; size_type right = m_size - 1; while (right + 1 != left) { _GLIBCXX_DEBUG_ASSERT(left <= m_size); if (!pred(m_a_entries[left])) ++left; else if (pred(m_a_entries[right])) --right; else { _GLIBCXX_DEBUG_ASSERT(left < right); std::swap(m_a_entries[left], m_a_entries[right]); ++left; --right; } } return left; } 8/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp000064400000021462152526447520015636 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/binary_heap_.hpp * Contains an implementation class for a binary heap. */ #ifndef PB_DS_BINARY_HEAP_HPP #define PB_DS_BINARY_HEAP_HPP #include #include #include #include #include #include #include #include #include #include #ifdef PB_DS_BINARY_HEAP_TRACE_ #include #endif #include #include namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ binary_heap #define PB_DS_ENTRY_CMP_DEC \ entry_cmp::value>::type #define PB_DS_RESIZE_POLICY_DEC \ __gnu_pbds::detail::resize_policy /** * Binary heaps composed of resize and compare policies. * * @ingroup heap-detail * * Based on CLRS. */ template class binary_heap : public PB_DS_ENTRY_CMP_DEC, public PB_DS_RESIZE_POLICY_DEC { public: typedef Value_Type value_type; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename PB_DS_ENTRY_CMP_DEC entry_cmp; typedef PB_DS_RESIZE_POLICY_DEC resize_policy; typedef cond_dealtor cond_dealtor_t; private: enum { simple_value = is_simple::value }; typedef integral_constant no_throw_copies_t; typedef typename _Alloc::template rebind __rebind_v; typedef typename __rebind_v::other value_allocator; public: typedef typename value_allocator::pointer pointer; typedef typename value_allocator::const_pointer const_pointer; typedef typename value_allocator::reference reference; typedef typename value_allocator::const_reference const_reference; typedef typename __conditional_type::__type entry; typedef typename _Alloc::template rebind::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; typedef binary_heap_point_const_iterator_ point_const_iterator; typedef point_const_iterator point_iterator; typedef binary_heap_const_iterator_ const_iterator; typedef const_iterator iterator; binary_heap(); binary_heap(const cmp_fn&); binary_heap(const binary_heap&); void swap(binary_heap&); ~binary_heap(); inline bool empty() const; inline size_type size() const; inline size_type max_size() const; Cmp_Fn& get_cmp_fn(); const Cmp_Fn& get_cmp_fn() const; inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline const_reference top() const; inline void pop(); inline void erase(point_iterator); template size_type erase_if(Pred); inline void erase_at(entry_pointer, size_type, false_type); inline void erase_at(entry_pointer, size_type, true_type); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; void clear(); template void split(Pred, binary_heap&); void join(binary_heap&); #ifdef PB_DS_BINARY_HEAP_TRACE_ void trace() const; #endif protected: template void copy_from_range(It, It); private: void value_swap(binary_heap&); inline void insert_value(const_reference, false_type); inline void insert_value(value_type, true_type); inline void resize_for_insert_if_needed(); inline void swap_value_imp(entry_pointer, value_type, true_type); inline void swap_value_imp(entry_pointer, const_reference, false_type); void fix(entry_pointer); inline const_reference top_imp(true_type) const; inline const_reference top_imp(false_type) const; inline static size_type left_child(size_type); inline static size_type right_child(size_type); inline static size_type parent(size_type); inline void resize_for_erase_if_needed(); template size_type partition(Pred); void make_heap() { const entry_cmp& m_cmp = static_cast(*this); entry_pointer end = m_a_entries + m_size; std::make_heap(m_a_entries, end, m_cmp); } void push_heap() { const entry_cmp& m_cmp = static_cast(*this); entry_pointer end = m_a_entries + m_size; std::push_heap(m_a_entries, end, m_cmp); } void pop_heap() { const entry_cmp& m_cmp = static_cast(*this); entry_pointer end = m_a_entries + m_size; std::pop_heap(m_a_entries, end, m_cmp); } #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_BINARY_HEAP_TRACE_ void trace_entry(const entry&, false_type) const; void trace_entry(const entry&, true_type) const; #endif static entry_allocator s_entry_allocator; static value_allocator s_value_allocator; static no_throw_copies_t s_no_throw_copies_ind; size_type m_size; size_type m_actual_size; entry_pointer m_a_entries; }; #define PB_DS_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);) #define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) #include #include #include #include #include #include #include #include #include #include #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_ENTRY_CMP_DEC #undef PB_DS_RESIZE_POLICY_DEC } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/binary_heap_/resize_policy.hpp000064400000013765152526447520016105 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/resize_policy.hpp * Contains an implementation class for a binary_heap. */ #ifndef PB_DS_BINARY_HEAP_RESIZE_POLICY_HPP #define PB_DS_BINARY_HEAP_RESIZE_POLICY_HPP #include namespace __gnu_pbds { namespace detail { /// Resize policy for binary heap. template class resize_policy { private: enum { ratio = 8, factor = 2 }; /// Next shrink size. _Tp m_shrink_size; /// Next grow size. _Tp m_grow_size; public: typedef _Tp size_type; static const _Tp min_size = 16; resize_policy() : m_shrink_size(0), m_grow_size(min_size) { PB_DS_ASSERT_VALID((*this)) } resize_policy(const resize_policy& other) : m_shrink_size(other.m_shrink_size), m_grow_size(other.m_grow_size) { PB_DS_ASSERT_VALID((*this)) } inline void swap(resize_policy<_Tp>&); inline bool resize_needed_for_grow(size_type) const; inline bool resize_needed_for_shrink(size_type) const; inline bool grow_needed(size_type) const; inline bool shrink_needed(size_type) const; inline size_type get_new_size_for_grow() const; inline size_type get_new_size_for_shrink() const; inline size_type get_new_size_for_arbitrary(size_type) const; inline void notify_grow_resize(); inline void notify_shrink_resize(); void notify_arbitrary(size_type); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_BINARY_HEAP_TRACE_ void trace() const; #endif }; template const _Tp resize_policy<_Tp>::min_size; template inline void resize_policy<_Tp>:: swap(resize_policy<_Tp>& other) { std::swap(m_shrink_size, other.m_shrink_size); std::swap(m_grow_size, other.m_grow_size); } template inline bool resize_policy<_Tp>:: resize_needed_for_grow(size_type size) const { _GLIBCXX_DEBUG_ASSERT(size <= m_grow_size); return size == m_grow_size; } template inline bool resize_policy<_Tp>:: resize_needed_for_shrink(size_type size) const { _GLIBCXX_DEBUG_ASSERT(size <= m_grow_size); return size == m_shrink_size; } template inline typename resize_policy<_Tp>::size_type resize_policy<_Tp>:: get_new_size_for_grow() const { return m_grow_size * factor; } template inline typename resize_policy<_Tp>::size_type resize_policy<_Tp>:: get_new_size_for_shrink() const { const size_type half_size = m_grow_size / factor; return std::max(min_size, half_size); } template inline typename resize_policy<_Tp>::size_type resize_policy<_Tp>:: get_new_size_for_arbitrary(size_type size) const { size_type ret = min_size; while (ret < size) ret *= factor; return ret; } template inline void resize_policy<_Tp>:: notify_grow_resize() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(m_grow_size >= min_size); m_grow_size *= factor; m_shrink_size = m_grow_size / ratio; PB_DS_ASSERT_VALID((*this)) } template inline void resize_policy<_Tp>:: notify_shrink_resize() { PB_DS_ASSERT_VALID((*this)) m_shrink_size /= factor; if (m_shrink_size == 1) m_shrink_size = 0; m_grow_size = std::max(m_grow_size / factor, min_size); PB_DS_ASSERT_VALID((*this)) } template inline void resize_policy<_Tp>:: notify_arbitrary(size_type actual_size) { m_grow_size = actual_size; m_shrink_size = m_grow_size / ratio; PB_DS_ASSERT_VALID((*this)) } #ifdef _GLIBCXX_DEBUG template void resize_policy<_Tp>:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_shrink_size == 0 || m_shrink_size * ratio == m_grow_size); PB_DS_DEBUG_VERIFY(m_grow_size >= min_size); } #endif #ifdef PB_DS_BINARY_HEAP_TRACE_ template void resize_policy<_Tp>:: trace() const { std::cerr << "shrink = " << m_shrink_size << " grow = " << m_grow_size << std::endl; } #endif } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp000064400000011473152526447520017104 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/split_join_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) typedef typename entry_pred::type pred_t; const size_type left = partition(pred_t(pred)); _GLIBCXX_DEBUG_ASSERT(m_size >= left); const size_type ersd = m_size - left; _GLIBCXX_DEBUG_ASSERT(m_size >= ersd); const size_type new_size = resize_policy::get_new_size_for_arbitrary(left); const size_type other_actual_size = other.get_new_size_for_arbitrary(ersd); entry_pointer a_entries = 0; entry_pointer a_other_entries = 0; __try { a_entries = s_entry_allocator.allocate(new_size); a_other_entries = s_entry_allocator.allocate(other_actual_size); } __catch(...) { if (a_entries != 0) s_entry_allocator.deallocate(a_entries, new_size); if (a_other_entries != 0) s_entry_allocator.deallocate(a_other_entries, other_actual_size); __throw_exception_again; }; for (size_type i = 0; i < other.m_size; ++i) erase_at(other.m_a_entries, i, s_no_throw_copies_ind); _GLIBCXX_DEBUG_ASSERT(new_size >= left); std::copy(m_a_entries, m_a_entries + left, a_entries); std::copy(m_a_entries + left, m_a_entries + m_size, a_other_entries); s_entry_allocator.deallocate(m_a_entries, m_actual_size); s_entry_allocator.deallocate(other.m_a_entries, other.m_actual_size); m_actual_size = new_size; other.m_actual_size = other_actual_size; m_size = left; other.m_size = ersd; m_a_entries = a_entries; other.m_a_entries = a_other_entries; make_heap(); other.make_heap(); resize_policy::notify_arbitrary(m_actual_size); other.notify_arbitrary(other.m_actual_size); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) const size_type len = m_size + other.m_size; const size_type new_size = resize_policy::get_new_size_for_arbitrary(len); entry_pointer a_entries = 0; entry_pointer a_other_entries = 0; __try { a_entries = s_entry_allocator.allocate(new_size); a_other_entries = s_entry_allocator.allocate(resize_policy::min_size); } __catch(...) { if (a_entries != 0) s_entry_allocator.deallocate(a_entries, new_size); if (a_other_entries != 0) s_entry_allocator.deallocate(a_other_entries, resize_policy::min_size); __throw_exception_again; } std::copy(m_a_entries, m_a_entries + m_size, a_entries); std::copy(other.m_a_entries, other.m_a_entries + other.m_size, a_entries + m_size); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_a_entries = a_entries; m_size = len; m_actual_size = new_size; resize_policy::notify_arbitrary(new_size); make_heap(); s_entry_allocator.deallocate(other.m_a_entries, other.m_actual_size); other.m_a_entries = a_other_entries; other.m_size = 0; other.m_actual_size = resize_policy::min_size; other.notify_arbitrary(resize_policy::min_size); other.make_heap(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } 8/ext/pb_ds/detail/splay_tree_/node.hpp000064400000007240152526447520014027 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/node.hpp * Contains an implementation struct for splay_tree_'s node. */ #ifndef PB_DS_SPLAY_TREE_NODE_HPP #define PB_DS_SPLAY_TREE_NODE_HPP namespace __gnu_pbds { namespace detail { /// Node for splay tree. template struct splay_tree_node_ { public: typedef Value_Type value_type; typedef Metadata metadata_type; typedef typename _Alloc::template rebind< splay_tree_node_ >::other::pointer node_pointer; typedef typename _Alloc::template rebind::other::reference metadata_reference; typedef typename _Alloc::template rebind::other::const_reference metadata_const_reference; #ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ void trace() const { std::cout << PB_DS_V2F(m_value) << "(" << m_metadata << ")"; } #endif inline bool special() const { return m_special; } inline metadata_const_reference get_metadata() const { return m_metadata; } inline metadata_reference get_metadata() { return m_metadata; } value_type m_value; bool m_special; node_pointer m_p_left; node_pointer m_p_right; node_pointer m_p_parent; metadata_type m_metadata; }; template struct splay_tree_node_ { public: typedef Value_Type value_type; typedef null_type metadata_type; typedef typename _Alloc::template rebind< splay_tree_node_ >::other::pointer node_pointer; inline bool special() const { return m_special; } #ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ void trace() const { std::cout << PB_DS_V2F(m_value); } #endif node_pointer m_p_left; node_pointer m_p_right; node_pointer m_p_parent; value_type m_value; bool m_special; }; } // namespace detail } // namespace __gnu_pbds #endif 8/ext/pb_ds/detail/splay_tree_/constructors_destructor_fn_imps.hpp000064400000005437152526447520021651 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/constructors_destructor_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_S_TREE_NAME() { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_S_TREE_NAME(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_S_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : base_type(r_cmp_fn, r_node_update) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_S_TREE_NAME(const PB_DS_CLASS_C_DEC& other) : base_type(other) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) base_type::swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { base_type::m_p_head->m_special = true; } 8/ext/pb_ds/detail/splay_tree_/info_fn_imps.hpp000064400000003231152526447520015544 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/info_fn_imps.hpp * Contains an implementation. */ 8/ext/pb_ds/detail/splay_tree_/find_fn_imps.hpp000064400000006367152526447520015546 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/find_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { node_pointer p_found = find_imp(r_key); if (p_found != base_type::m_p_head) splay(p_found); return point_iterator(p_found); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { const node_pointer p_found = find_imp(r_key); if (p_found != base_type::m_p_head) const_cast(this)->splay(p_found); return point_iterator(p_found); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: find_imp(key_const_reference r_key) { _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid(__FILE__, __LINE__);) node_pointer p_nd = base_type::m_p_head->m_p_parent; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) { if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) return p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; return base_type::m_p_head; } PB_DS_CLASS_T_DEC inline const typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: find_imp(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = base_type::m_p_head->m_p_parent; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) { if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) return p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; return base_type::m_p_head; } 8/ext/pb_ds/detail/splay_tree_/splay_tree_.hpp000064400000022133152526447520015406 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/splay_tree_.hpp * Contains an implementation class for splay trees. */ /* * This implementation uses an idea from the SGI STL (using a @a header node * which is needed for efficient iteration). Following is the SGI STL * copyright. * * Copyright (c) 1996,1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * */ #include #include #include #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR # define PB_DS_S_TREE_NAME splay_tree_map # define PB_DS_S_TREE_BASE_NAME bin_search_tree_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR # define PB_DS_S_TREE_NAME splay_tree_set # define PB_DS_S_TREE_BASE_NAME bin_search_tree_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_S_TREE_NAME #define PB_DS_S_TREE_BASE \ PB_DS_S_TREE_BASE_NAME /** * @brief Splay tree. * @ingroup branch-detail */ template class PB_DS_S_TREE_NAME : public PB_DS_S_TREE_BASE { private: typedef PB_DS_S_TREE_BASE base_type; #ifdef _GLIBCXX_DEBUG typedef base_type debug_base; #endif typedef typename base_type::node_pointer node_pointer; public: typedef splay_tree_tag container_category; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Cmp_Fn cmp_fn; typedef typename base_type::key_type key_type; typedef typename base_type::key_pointer key_pointer; typedef typename base_type::key_const_pointer key_const_pointer; typedef typename base_type::key_reference key_reference; typedef typename base_type::key_const_reference key_const_reference; typedef typename base_type::mapped_type mapped_type; typedef typename base_type::mapped_pointer mapped_pointer; typedef typename base_type::mapped_const_pointer mapped_const_pointer; typedef typename base_type::mapped_reference mapped_reference; typedef typename base_type::mapped_const_reference mapped_const_reference; typedef typename base_type::value_type value_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator point_const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::reverse_iterator reverse_iterator; typedef typename base_type::const_reverse_iterator const_reverse_iterator; typedef typename base_type::node_update node_update; PB_DS_S_TREE_NAME(); PB_DS_S_TREE_NAME(const Cmp_Fn&); PB_DS_S_TREE_NAME(const Cmp_Fn&, const node_update&); PB_DS_S_TREE_NAME(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); template void copy_from_range(It, It); void initialize(); inline std::pair insert(const_reference r_value); inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) std::pair ins_pair = insert_leaf_imp(value_type(r_key, mapped_type())); ins_pair.first.m_p_nd->m_special = false; _GLIBCXX_DEBUG_ONLY(base_type::assert_valid(__FILE__, __LINE__)); splay(ins_pair.first.m_p_nd); _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return ins_pair.first.m_p_nd->m_value.second; #else insert(r_key); return base_type::s_null_type; #endif } inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline bool erase(key_const_reference); inline iterator erase(iterator it); inline reverse_iterator erase(reverse_iterator); template inline size_type erase_if(Pred); void join(PB_DS_CLASS_C_DEC&); void split(key_const_reference, PB_DS_CLASS_C_DEC&); private: inline std::pair insert_leaf_imp(const_reference); inline node_pointer find_imp(key_const_reference); inline const node_pointer find_imp(key_const_reference) const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char* file, int line) const; void assert_special_imp(const node_pointer, const char* file, int line) const; #endif void splay(node_pointer); inline void splay_zig_zag_left(node_pointer, node_pointer, node_pointer); inline void splay_zig_zag_right(node_pointer, node_pointer, node_pointer); inline void splay_zig_zig_left(node_pointer, node_pointer, node_pointer); inline void splay_zig_zig_right(node_pointer, node_pointer, node_pointer); inline void splay_zz_start(node_pointer, node_pointer, node_pointer); inline void splay_zz_end(node_pointer, node_pointer, node_pointer); inline node_pointer leftmost(node_pointer); void erase_node(node_pointer); }; #define PB_DS_ASSERT_BASE_NODE_CONSISTENT(_Node) \ _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(_Node, \ __FILE__, __LINE__);) #include #include #include #include #include #include #include #undef PB_DS_ASSERT_BASE_NODE_CONSISTENT #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_S_TREE_NAME #undef PB_DS_S_TREE_BASE_NAME #undef PB_DS_S_TREE_BASE } // namespace detail } // namespace __gnu_pbds 8/ext/pb_ds/detail/splay_tree_/debug_fn_imps.hpp000064400000004637152526447520015712 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/debug_fn_imps.hpp * Contains an implementation class for splay_tree_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(__file, __line); const node_pointer p_head = base_type::m_p_head; assert_special_imp(p_head, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_special_imp(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) return; if (p_nd == base_type::m_p_head) { PB_DS_DEBUG_VERIFY(p_nd->m_special); assert_special_imp(p_nd->m_p_parent, __file, __line); return; } PB_DS_DEBUG_VERIFY(!p_nd->m_special); assert_special_imp(p_nd->m_p_left, __file, __line); assert_special_imp(p_nd->m_p_right, __file, __line); } #endif 8/ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp000064400000006431152526447520016122 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/insert_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert(const_reference r_value) { PB_DS_ASSERT_VALID((*this)) std::pair ins_pair = insert_leaf_imp(r_value); ins_pair.first.m_p_nd->m_special = false; PB_DS_ASSERT_VALID((*this)) splay(ins_pair.first.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ins_pair; } PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert_leaf_imp(const_reference r_value) { _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid(__FILE__, __LINE__);) if (base_type::m_size == 0) return std::make_pair(base_type::insert_imp_empty(r_value), true); node_pointer p_nd = base_type::m_p_head->m_p_parent; node_pointer p_pot = base_type::m_p_head; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(r_value))) { if (!Cmp_Fn::operator()(PB_DS_V2F(r_value), PB_DS_V2F(p_nd->m_value))) { return std::make_pair(point_iterator(p_nd), false); } p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; if (p_pot == base_type::m_p_head) return std::make_pair(base_type::insert_leaf_new(r_value, base_type::m_p_head->m_p_right, false), true); PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_value)) p_nd = p_pot->m_p_left; if (p_nd == 0) return (std::make_pair(base_type::insert_leaf_new(r_value, p_pot, true), true)); while (p_nd->m_p_right != 0) p_nd = p_nd->m_p_right; return std::make_pair(this->insert_leaf_new(r_value, p_nd, false), true); } 8/ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp000064400000010255152526447520015714 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/erase_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { point_iterator it = find(r_key); if (it == base_type::end()) return false; erase(it); return true; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: erase(iterator it) { PB_DS_ASSERT_VALID((*this)) if (it == base_type::end()) return it; iterator ret_it = it; ++ret_it; erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ret_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: erase(reverse_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it.m_p_nd == base_type::m_p_head) return (it); reverse_iterator ret_it = it; ++ret_it; erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ret_it; } PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) size_type num_ersd = 0; iterator it = base_type::begin(); while (it != base_type::end()) { if (pred(*it)) { ++num_ersd; it = erase(it); } else ++it; } PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_node(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); splay(p_nd); PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(p_nd == this->m_p_head->m_p_parent); node_pointer p_l = p_nd->m_p_left; node_pointer p_r = p_nd->m_p_right; base_type::update_min_max_for_erased_node(p_nd); base_type::actual_erase_node(p_nd); if (p_r == 0) { base_type::m_p_head->m_p_parent = p_l; if (p_l != 0) p_l->m_p_parent = base_type::m_p_head; PB_DS_ASSERT_VALID((*this)) return; } node_pointer p_target_r = leftmost(p_r); _GLIBCXX_DEBUG_ASSERT(p_target_r != 0); p_r->m_p_parent = base_type::m_p_head; base_type::m_p_head->m_p_parent = p_r; splay(p_target_r); _GLIBCXX_DEBUG_ONLY(p_target_r->m_p_left = 0); _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_parent == this->m_p_head); _GLIBCXX_DEBUG_ASSERT(this->m_p_head->m_p_parent == p_target_r); p_target_r->m_p_left = p_l; if (p_l != 0) p_l->m_p_parent = p_target_r; PB_DS_ASSERT_VALID((*this)) this->apply_update(p_target_r, (node_update*)this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: leftmost(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); while (p_nd->m_p_left != 0) p_nd = p_nd->m_p_left; return p_nd; } 8/ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp000064400000017561152526447520015754 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/splay_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: splay(node_pointer p_nd) { while (p_nd->m_p_parent != base_type::m_p_head) { #ifdef _GLIBCXX_DEBUG { node_pointer p_head = base_type::m_p_head; assert_special_imp(p_head, __FILE__, __LINE__); } #endif PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_nd) if (p_nd->m_p_parent->m_p_parent == base_type::m_p_head) { base_type::rotate_parent(p_nd); _GLIBCXX_DEBUG_ASSERT(p_nd == this->m_p_head->m_p_parent); } else { const node_pointer p_parent = p_nd->m_p_parent; const node_pointer p_grandparent = p_parent->m_p_parent; #ifdef _GLIBCXX_DEBUG const size_type total = base_type::recursive_count(p_grandparent); _GLIBCXX_DEBUG_ASSERT(total >= 3); #endif if (p_parent->m_p_left == p_nd && p_grandparent->m_p_right == p_parent) splay_zig_zag_left(p_nd, p_parent, p_grandparent); else if (p_parent->m_p_right == p_nd && p_grandparent->m_p_left == p_parent) splay_zig_zag_right(p_nd, p_parent, p_grandparent); else if (p_parent->m_p_left == p_nd && p_grandparent->m_p_left == p_parent) splay_zig_zig_left(p_nd, p_parent, p_grandparent); else splay_zig_zig_right(p_nd, p_parent, p_grandparent); _GLIBCXX_DEBUG_ASSERT(total ==this->recursive_count(p_nd)); } PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_nd) } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zig_zag_left(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_grandparent) _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_left == p_nd && p_grandparent->m_p_right == p_parent); splay_zz_start(p_nd, p_parent, p_grandparent); node_pointer p_b = p_nd->m_p_right; node_pointer p_c = p_nd->m_p_left; p_nd->m_p_right = p_parent; p_parent->m_p_parent = p_nd; p_nd->m_p_left = p_grandparent; p_grandparent->m_p_parent = p_nd; p_parent->m_p_left = p_b; if (p_b != 0) p_b->m_p_parent = p_parent; p_grandparent->m_p_right = p_c; if (p_c != 0) p_c->m_p_parent = p_grandparent; splay_zz_end(p_nd, p_parent, p_grandparent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zig_zag_right(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_grandparent) _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_right == p_nd && p_grandparent->m_p_left == p_parent); splay_zz_start(p_nd, p_parent, p_grandparent); node_pointer p_b = p_nd->m_p_left; node_pointer p_c = p_nd->m_p_right; p_nd->m_p_left = p_parent; p_parent->m_p_parent = p_nd; p_nd->m_p_right = p_grandparent; p_grandparent->m_p_parent = p_nd; p_parent->m_p_right = p_b; if (p_b != 0) p_b->m_p_parent = p_parent; p_grandparent->m_p_left = p_c; if (p_c != 0) p_c->m_p_parent = p_grandparent; splay_zz_end(p_nd, p_parent, p_grandparent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zig_zig_left(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_grandparent) _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_left == p_nd && p_nd->m_p_parent->m_p_parent->m_p_left == p_nd->m_p_parent); splay_zz_start(p_nd, p_parent, p_grandparent); node_pointer p_b = p_nd->m_p_right; node_pointer p_c = p_parent->m_p_right; p_nd->m_p_right = p_parent; p_parent->m_p_parent = p_nd; p_parent->m_p_right = p_grandparent; p_grandparent->m_p_parent = p_parent; p_parent->m_p_left = p_b; if (p_b != 0) p_b->m_p_parent = p_parent; p_grandparent->m_p_left = p_c; if (p_c != 0) p_c->m_p_parent = p_grandparent; splay_zz_end(p_nd, p_parent, p_grandparent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zig_zig_right(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_grandparent) _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_right == p_nd && p_nd->m_p_parent->m_p_parent->m_p_right == p_nd->m_p_parent); splay_zz_start(p_nd, p_parent, p_grandparent); node_pointer p_b = p_nd->m_p_left; node_pointer p_c = p_parent->m_p_left; p_nd->m_p_left = p_parent; p_parent->m_p_parent = p_nd; p_parent->m_p_left = p_grandparent; p_grandparent->m_p_parent = p_parent; p_parent->m_p_right = p_b; if (p_b != 0) p_b->m_p_parent = p_parent; p_grandparent->m_p_right = p_c; if (p_c != 0) p_c->m_p_parent = p_grandparent; base_type::update_to_top(p_grandparent, (node_update*)this); splay_zz_end(p_nd, p_parent, p_grandparent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zz_start(node_pointer p_nd, #ifdef _GLIBCXX_DEBUG node_pointer p_parent, #else node_pointer /*p_parent*/, #endif node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_parent != 0); _GLIBCXX_DEBUG_ASSERT(p_grandparent != 0); const bool grandparent_head = p_grandparent->m_p_parent == base_type::m_p_head; if (grandparent_head) { base_type::m_p_head->m_p_parent = base_type::m_p_head->m_p_parent; p_nd->m_p_parent = base_type::m_p_head; return; } node_pointer p_greatgrandparent = p_grandparent->m_p_parent; p_nd->m_p_parent = p_greatgrandparent; if (p_grandparent == p_greatgrandparent->m_p_left) p_greatgrandparent->m_p_left = p_nd; else p_greatgrandparent->m_p_right = p_nd; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zz_end(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { if (p_nd->m_p_parent == base_type::m_p_head) base_type::m_p_head->m_p_parent = p_nd; this->apply_update(p_grandparent, (node_update*)this); this->apply_update(p_parent, (node_update*)this); this->apply_update(p_nd, (node_update*)this); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_nd) } 8/ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hpp000064400000007062152526447520016771 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/split_join_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (base_type::join_prep(other) == false) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } node_pointer p_target_r = other.leftmost(other.m_p_head); _GLIBCXX_DEBUG_ASSERT(p_target_r != 0); other.splay(p_target_r); _GLIBCXX_DEBUG_ASSERT(p_target_r == other.m_p_head->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_left == 0); p_target_r->m_p_left = base_type::m_p_head->m_p_parent; _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_left != 0); p_target_r->m_p_left->m_p_parent = p_target_r; base_type::m_p_head->m_p_parent = p_target_r; p_target_r->m_p_parent = base_type::m_p_head; this->apply_update(p_target_r, (node_update*)this); base_type::join_finish(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (base_type::split_prep(r_key, other) == false) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } node_pointer p_upper_bound = this->upper_bound(r_key).m_p_nd; _GLIBCXX_DEBUG_ASSERT(p_upper_bound != 0); splay(p_upper_bound); _GLIBCXX_DEBUG_ASSERT(p_upper_bound->m_p_parent == this->m_p_head); node_pointer p_new_root = p_upper_bound->m_p_left; _GLIBCXX_DEBUG_ASSERT(p_new_root != 0); base_type::m_p_head->m_p_parent = p_new_root; p_new_root->m_p_parent = base_type::m_p_head; other.m_p_head->m_p_parent = p_upper_bound; p_upper_bound->m_p_parent = other.m_p_head; p_upper_bound->m_p_left = 0; this->apply_update(p_upper_bound, (node_update*)this); base_type::split_finish(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } 8/ext/pb_ds/detail/splay_tree_/traits.hpp000064400000006427152526447520014416 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/traits.hpp * Contains an implementation for splay_tree_. */ #ifndef PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP #define PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP #include namespace __gnu_pbds { namespace detail { /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct tree_traits : public bin_search_tree_traits::value_type, typename tree_node_metadata_dispatch::type, _Alloc>, _Alloc> { }; /// Specialization. /// @ingroup traits template class Node_Update, typename _Alloc> struct tree_traits : public bin_search_tree_traits::value_type, typename tree_node_metadata_dispatch::type, _Alloc>, _Alloc> { }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP 8/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp000064400000046761152526447520016416 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/cc_ht_map_.hpp * Contains an implementation class for cc_ht_map_. */ #include #include #include #include #include #include #include #include #ifdef _GLIBCXX_DEBUG #include #endif #ifdef PB_DS_HT_MAP_TRACE_ #include #endif #include namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_CC_HASH_NAME cc_ht_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_CC_HASH_NAME cc_ht_set #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ PB_DS_CC_HASH_NAME #define PB_DS_HASH_EQ_FN_C_DEC \ hash_eq_fn #define PB_DS_RANGED_HASH_FN_C_DEC \ ranged_hash_fn #define PB_DS_CC_HASH_TRAITS_BASE \ types_traits #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base::other::const_reference> #endif /** * A collision-chaining hash-based container. * * * @ingroup hash-detail * * @tparam Key Key type. * * @tparam Mapped Map type. * * @tparam Hash_Fn Hashing functor. * Default is __gnu_cxx::hash. * * @tparam Eq_Fn Equal functor. * Default std::equal_to * * @tparam _Alloc Allocator type. * * @tparam Store_Hash If key type stores extra metadata. * Defaults to false. * * @tparam Comb_Hash_Fn Combining hash functor. * If Hash_Fn is not null_type, then this * is the ranged-hash functor; otherwise, * this is the range-hashing functor. * XXX(See Design::Hash-Based Containers::Hash Policies.) * Default direct_mask_range_hashing. * * @tparam Resize_Policy Resizes hash. * Defaults to hash_standard_resize_policy, * using hash_exponential_size_policy and * hash_load_check_resize_trigger. * * * Bases are: detail::hash_eq_fn, Resize_Policy, detail::ranged_hash_fn, * detail::types_traits. (Optional: detail::debug_map_base.) */ template class PB_DS_CC_HASH_NAME: #ifdef _GLIBCXX_DEBUG protected PB_DS_DEBUG_MAP_BASE_C_DEC, #endif public PB_DS_HASH_EQ_FN_C_DEC, public Resize_Policy, public PB_DS_RANGED_HASH_FN_C_DEC, public PB_DS_CC_HASH_TRAITS_BASE { private: typedef PB_DS_CC_HASH_TRAITS_BASE traits_base; typedef typename traits_base::comp_hash comp_hash; typedef typename traits_base::value_type value_type_; typedef typename traits_base::pointer pointer_; typedef typename traits_base::const_pointer const_pointer_; typedef typename traits_base::reference reference_; typedef typename traits_base::const_reference const_reference_; struct entry : public traits_base::stored_data_type { typename _Alloc::template rebind::other::pointer m_p_next; }; typedef cond_dealtor cond_dealtor_t; typedef typename _Alloc::template rebind::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; typedef typename entry_allocator::const_pointer const_entry_pointer; typedef typename entry_allocator::reference entry_reference; typedef typename entry_allocator::const_reference const_entry_reference; typedef typename _Alloc::template rebind::other entry_pointer_allocator; typedef typename entry_pointer_allocator::pointer entry_pointer_array; typedef PB_DS_RANGED_HASH_FN_C_DEC ranged_hash_fn_base; typedef PB_DS_HASH_EQ_FN_C_DEC hash_eq_fn_base; typedef Resize_Policy resize_base; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif #define PB_DS_GEN_POS std::pair #include #include #include #include #undef PB_DS_GEN_POS public: typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Hash_Fn hash_fn; typedef Eq_Fn eq_fn; typedef Comb_Hash_Fn comb_hash_fn; typedef Resize_Policy resize_policy; /// Value stores hash, true or false. enum { store_hash = Store_Hash }; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef point_iterator_ point_iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef point_const_iterator_ point_iterator; #endif typedef point_const_iterator_ point_const_iterator; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef iterator_ iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef const_iterator_ iterator; #endif typedef const_iterator_ const_iterator; PB_DS_CC_HASH_NAME(); PB_DS_CC_HASH_NAME(const Hash_Fn&); PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&); PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&); PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&, const Resize_Policy&); PB_DS_CC_HASH_NAME(const PB_DS_CLASS_C_DEC&); virtual ~PB_DS_CC_HASH_NAME(); void swap(PB_DS_CLASS_C_DEC&); template void copy_from_range(It, It); void initialize(); inline size_type size() const; inline size_type max_size() const; /// True if size() == 0. inline bool empty() const; /// Return current hash_fn. Hash_Fn& get_hash_fn(); /// Return current const hash_fn. const Hash_Fn& get_hash_fn() const; /// Return current eq_fn. Eq_Fn& get_eq_fn(); /// Return current const eq_fn. const Eq_Fn& get_eq_fn() const; /// Return current comb_hash_fn. Comb_Hash_Fn& get_comb_hash_fn(); /// Return current const comb_hash_fn. const Comb_Hash_Fn& get_comb_hash_fn() const; /// Return current resize_policy. Resize_Policy& get_resize_policy(); /// Return current const resize_policy. const Resize_Policy& get_resize_policy() const; inline std::pair insert(const_reference r_val) { return insert_imp(r_val, traits_base::m_store_extra_indicator); } inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR return (subscript_imp(r_key, traits_base::m_store_extra_indicator)); #else insert(r_key); return traits_base::s_null_type; #endif } inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline point_iterator find_end(); inline point_const_iterator find_end() const; inline bool erase(key_const_reference); template inline size_type erase_if(Pred); void clear(); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_HT_MAP_TRACE_ void trace() const; #endif private: void deallocate_all(); inline bool do_resize_if_needed(); inline void do_resize_if_needed_no_throw(); void resize_imp(size_type); void do_resize(size_type); void resize_imp_no_exceptions(size_type, entry_pointer_array, size_type); inline entry_pointer resize_imp_no_exceptions_reassign_pointer(entry_pointer, entry_pointer_array, false_type); inline entry_pointer resize_imp_no_exceptions_reassign_pointer(entry_pointer, entry_pointer_array, true_type); void deallocate_links_in_list(entry_pointer); inline entry_pointer get_entry(const_reference, false_type); inline entry_pointer get_entry(const_reference, true_type); inline void rels_entry(entry_pointer); #ifdef PB_DS_DATA_TRUE_INDICATOR inline mapped_reference subscript_imp(key_const_reference r_key, false_type) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) const size_type pos = ranged_hash_fn_base::operator()(r_key); entry_pointer p_e = m_entries[pos]; resize_base::notify_insert_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(p_e->m_value.first, r_key)) { resize_base::notify_insert_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_insert_search_end(); if (p_e != 0) { PB_DS_CHECK_KEY_EXISTS(r_key) return (p_e->m_value.second); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return insert_new_imp(value_type(r_key, mapped_type()), pos)->second; } inline mapped_reference subscript_imp(key_const_reference r_key, true_type) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key); entry_pointer p_e = m_entries[pos_hash_pair.first]; resize_base::notify_insert_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(p_e->m_value.first, p_e->m_hash, r_key, pos_hash_pair.second)) { resize_base::notify_insert_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_insert_search_end(); if (p_e != 0) { PB_DS_CHECK_KEY_EXISTS(r_key) return p_e->m_value.second; } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return insert_new_imp(value_type(r_key, mapped_type()), pos_hash_pair)->second; } #endif inline std::pair insert_imp(const_reference, false_type); inline std::pair insert_imp(const_reference, true_type); inline pointer insert_new_imp(const_reference r_val, size_type pos) { if (do_resize_if_needed()) pos = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val)); // Following lines might throw an exception. entry_pointer p_e = get_entry(r_val, traits_base::m_no_throw_copies_indicator); // At this point no exceptions can be thrown. p_e->m_p_next = m_entries[pos]; m_entries[pos] = p_e; resize_base::notify_inserted(++m_num_used_e); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return &p_e->m_value; } inline pointer insert_new_imp(const_reference r_val, comp_hash& r_pos_hash_pair) { // Following lines might throw an exception. if (do_resize_if_needed()) r_pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val)); entry_pointer p_e = get_entry(r_val, traits_base::m_no_throw_copies_indicator); // At this point no exceptions can be thrown. p_e->m_hash = r_pos_hash_pair.second; p_e->m_p_next = m_entries[r_pos_hash_pair.first]; m_entries[r_pos_hash_pair.first] = p_e; resize_base::notify_inserted(++m_num_used_e); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return &p_e->m_value; } inline pointer find_key_pointer(key_const_reference r_key, false_type) { entry_pointer p_e = m_entries[ranged_hash_fn_base::operator()(r_key)]; resize_base::notify_find_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_find_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_find_search_end(); #ifdef _GLIBCXX_DEBUG if (p_e == 0) PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) else PB_DS_CHECK_KEY_EXISTS(r_key) #endif return &p_e->m_value; } inline pointer find_key_pointer(key_const_reference r_key, true_type) { comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key); entry_pointer p_e = m_entries[pos_hash_pair.first]; resize_base::notify_find_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, r_key, pos_hash_pair.second)) { resize_base::notify_find_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_find_search_end(); #ifdef _GLIBCXX_DEBUG if (p_e == 0) PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) else PB_DS_CHECK_KEY_EXISTS(r_key) #endif return &p_e->m_value; } inline bool erase_in_pos_imp(key_const_reference, size_type); inline bool erase_in_pos_imp(key_const_reference, const comp_hash&); inline void erase_entry_pointer(entry_pointer&); #ifdef PB_DS_DATA_TRUE_INDICATOR void inc_it_state(pointer& r_p_value, std::pair& r_pos) const { inc_it_state((mapped_const_pointer& )r_p_value, r_pos); } #endif void inc_it_state(const_pointer& r_p_value, std::pair& r_pos) const { _GLIBCXX_DEBUG_ASSERT(r_p_value != 0); r_pos.first = r_pos.first->m_p_next; if (r_pos.first != 0) { r_p_value = &r_pos.first->m_value; return; } for (++r_pos.second; r_pos.second < m_num_e; ++r_pos.second) if (m_entries[r_pos.second] != 0) { r_pos.first = m_entries[r_pos.second]; r_p_value = &r_pos.first->m_value; return; } r_p_value = 0; } void get_start_it_state(pointer& r_p_value, std::pair& r_pos) const { for (r_pos.second = 0; r_pos.second < m_num_e; ++r_pos.second) if (m_entries[r_pos.second] != 0) { r_pos.first = m_entries[r_pos.second]; r_p_value = &r_pos.first->m_value; return; } r_p_value = 0; } #ifdef _GLIBCXX_DEBUG void assert_entry_pointer_array_valid(const entry_pointer_array, const char*, int) const; void assert_entry_pointer_valid(const entry_pointer, true_type, const char*, int) const; void assert_entry_pointer_valid(const entry_pointer, false_type, const char*, int) const; #endif #ifdef PB_DS_HT_MAP_TRACE_ void trace_list(const_entry_pointer) const; #endif private: #ifdef PB_DS_DATA_TRUE_INDICATOR friend class iterator_; #endif friend class const_iterator_; static entry_allocator s_entry_allocator; static entry_pointer_allocator s_entry_pointer_allocator; static iterator s_end_it; static const_iterator s_const_end_it; static point_iterator s_find_end_it; static point_const_iterator s_const_find_end_it; size_type m_num_e; size_type m_num_used_e; entry_pointer_array m_entries; enum { store_hash_ok = !Store_Hash || !is_same::value }; PB_DS_STATIC_ASSERT(sth, store_hash_ok); }; #include #include #include #include #include #include #include #include #include #include #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_HASH_EQ_FN_C_DEC #undef PB_DS_RANGED_HASH_FN_C_DEC #undef PB_DS_CC_HASH_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #undef PB_DS_CC_HASH_NAME } // namespace detail } // namespace __gnu_pbds 8/ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp000064400000007736152526447520017355 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/resize_fn_imps.hpp * Contains implementations of cc_ht_map_'s resize related functions. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: do_resize_if_needed() { if (!resize_base::is_resize_needed()) return false; resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: do_resize(size_type len) { resize_imp(resize_base::get_nearest_larger_size(len)); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: do_resize_if_needed_no_throw() { if (!resize_base::is_resize_needed()) return; __try { resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); } __catch(...) { } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize_imp(size_type new_size) { PB_DS_ASSERT_VALID((*this)) if (new_size == m_num_e) return; const size_type old_size = m_num_e; entry_pointer_array a_p_entries_resized; // Following line might throw an exception. ranged_hash_fn_base::notify_resized(new_size); __try { // Following line might throw an exception. a_p_entries_resized = s_entry_pointer_allocator.allocate(new_size); m_num_e = new_size; } __catch(...) { ranged_hash_fn_base::notify_resized(old_size); __throw_exception_again; } // At this point no exceptions can be thrown. resize_imp_no_exceptions(new_size, a_p_entries_resized, old_size); Resize_Policy::notify_resized(new_size); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize_imp_no_exceptions(size_type new_size, entry_pointer_array a_p_entries_resized, size_type old_size) { std::fill(a_p_entries_resized, a_p_entries_resized + m_num_e, entry_pointer(0)); for (size_type pos = 0; pos < old_size; ++pos) { entry_pointer p_e = m_entries[pos]; while (p_e != 0) p_e = resize_imp_no_exceptions_reassign_pointer(p_e, a_p_entries_resized, traits_base::m_store_extra_indicator); } m_num_e = new_size; _GLIBCXX_DEBUG_ONLY(assert_entry_pointer_array_valid(a_p_entries_resized, __FILE__, __LINE__);) s_entry_pointer_allocator.deallocate(m_entries, old_size); m_entries = a_p_entries_resized; PB_DS_ASSERT_VALID((*this)) } #include #include 8/ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp000064400000004302152526447520022252 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s resize related functions, when the * hash value is not stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: resize_imp_no_exceptions_reassign_pointer(entry_pointer p_e, entry_pointer_array a_p_entries_resized, false_type) { const size_type hash_pos = ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value)); entry_pointer const p_next_e = p_e->m_p_next; p_e->m_p_next = a_p_entries_resized[hash_pos]; a_p_entries_resized[hash_pos] = p_e; return p_next_e; } 8/ext/pb_ds/detail/cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp000064400000005472152526447520022112 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp * Contains a conditional key destructor, used for exception handling. */ namespace __gnu_pbds { namespace detail { /// Conditional dey destructor, cc_hash. template class cond_dealtor { public: typedef typename HT_Map::entry entry; typedef typename HT_Map::entry_allocator entry_allocator; typedef typename HT_Map::key_type key_type; cond_dealtor(entry_allocator* p_a, entry* p_e) : m_p_a(p_a), m_p_e(p_e), m_key_destruct(false), m_no_action_destructor(false) { } inline ~cond_dealtor(); void set_key_destruct() { m_key_destruct = true; } void set_no_action_destructor() { m_no_action_destructor = true; } protected: entry_allocator* const m_p_a; entry* const m_p_e; bool m_key_destruct; bool m_no_action_destructor; }; template inline cond_dealtor:: ~cond_dealtor() { if (m_no_action_destructor) return; if (m_key_destruct) m_p_e->m_value.first.~key_type(); m_p_a->deallocate(m_p_e, 1); } } // namespace detail } // namespace __gnu_pbds 8/ext/pb_ds/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp000064400000006300152526447520022050 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s erase related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) return erase_in_pos_imp(r_key, ranged_hash_fn_base::operator()(r_key)); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase_in_pos_imp(key_const_reference r_key, size_type pos) { PB_DS_ASSERT_VALID((*this)) entry_pointer p_e = m_entries[pos]; resize_base::notify_erase_search_start(); if (p_e == 0) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) PB_DS_ASSERT_VALID((*this)) return false; } if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) erase_entry_pointer(m_entries[pos]); do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return true; } while (true) { entry_pointer p_next_e = p_e->m_p_next; if (p_next_e == 0) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) PB_DS_ASSERT_VALID((*this)) return false; } if (hash_eq_fn_base::operator()(PB_DS_V2F(p_next_e->m_value), r_key)) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) erase_entry_pointer(p_e->m_p_next); do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return true; } resize_base::notify_erase_search_collision(); p_e = p_next_e; } } 8/ext/pb_ds/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp000064400000005072152526447520022262 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s insert related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert_imp(const_reference r_val, false_type) { PB_DS_ASSERT_VALID((*this)) key_const_reference r_key = PB_DS_V2F(r_val); const size_type pos = ranged_hash_fn_base::operator()(r_key); entry_pointer p_e = m_entries[pos]; resize_base::notify_insert_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_insert_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_insert_search_end(); if (p_e != 0) { PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(&p_e->m_value, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return std::make_pair(insert_new_imp(r_val, pos), true); } 8/ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp000064400000004473152526447520017145 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/trace_fn_imps.hpp * Contains implementations of cc_ht_map_'s trace-mode functions. */ #ifdef PB_DS_HT_MAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << static_cast(m_num_e) << " " << static_cast(m_num_used_e) << std::endl; for (size_type i = 0; i < m_num_e; ++i) { std::cerr << static_cast(i) << " "; trace_list(m_entries[i]); std::cerr << std::endl; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_list(const_entry_pointer p_l) const { size_type iterated_num_used_e = 0; while (p_l != 0) { std::cerr << PB_DS_V2F(p_l->m_value) << " "; p_l = p_l->m_p_next; } } #endif 8/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp000064400000013237152526447520022710 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/constructor_destructor_fn_imps.hpp * Contains implementations of cc_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_allocator PB_DS_CLASS_C_DEC::s_entry_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_pointer_allocator PB_DS_CLASS_C_DEC::s_entry_pointer_allocator; PB_DS_CLASS_T_DEC template void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME() : ranged_hash_fn_base(resize_base::get_nearest_larger_size(1)), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const Hash_Fn& r_hash_fn) : ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn) : PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { std::fill(m_entries, m_entries + m_num_e, (entry_pointer)0); Resize_Policy::notify_cleared(); ranged_hash_fn_base::notify_resized(m_num_e); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Hash_Fn& r_comb_hash_fn) : PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, r_comb_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Hash_Fn& r_comb_hash_fn, const Resize_Policy& r_resize_policy) : PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), Resize_Policy(r_resize_policy), ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, r_comb_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const PB_DS_CLASS_C_DEC& other) : PB_DS_HASH_EQ_FN_C_DEC(other), resize_base(other), ranged_hash_fn_base(other), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) __try { copy_from_range(other.begin(), other.end()); } __catch(...) { deallocate_all(); __throw_exception_again; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_CC_HASH_NAME() { deallocate_all(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) std::swap(m_entries, other.m_entries); std::swap(m_num_e, other.m_num_e); std::swap(m_num_used_e, other.m_num_used_e); ranged_hash_fn_base::swap(other); hash_eq_fn_base::swap(other); resize_base::swap(other); _GLIBCXX_DEBUG_ONLY(debug_base::swap(other)); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: deallocate_all() { clear(); s_entry_pointer_allocator.deallocate(m_entries, m_num_e); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { std::fill(m_entries, m_entries + m_num_e, entry_pointer(0)); Resize_Policy::notify_resized(m_num_e); Resize_Policy::notify_cleared(); ranged_hash_fn_base::notify_resized(m_num_e); } 8/ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp000064400000004661152526447520020666 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/policy_access_fn_imps.hpp * Contains implementations of cc_ht_map_'s policy access * functions. */ PB_DS_CLASS_T_DEC Hash_Fn& PB_DS_CLASS_C_DEC:: get_hash_fn() { return *this; } PB_DS_CLASS_T_DEC const Hash_Fn& PB_DS_CLASS_C_DEC:: get_hash_fn() const { return *this; } PB_DS_CLASS_T_DEC Eq_Fn& PB_DS_CLASS_C_DEC:: get_eq_fn() { return *this; } PB_DS_CLASS_T_DEC const Eq_Fn& PB_DS_CLASS_C_DEC:: get_eq_fn() const { return *this; } PB_DS_CLASS_T_DEC Comb_Hash_Fn& PB_DS_CLASS_C_DEC:: get_comb_hash_fn() { return *this; } PB_DS_CLASS_T_DEC const Comb_Hash_Fn& PB_DS_CLASS_C_DEC:: get_comb_hash_fn() const { return *this; } PB_DS_CLASS_T_DEC Resize_Policy& PB_DS_CLASS_C_DEC:: get_resize_policy() { return *this; } PB_DS_CLASS_T_DEC const Resize_Policy& PB_DS_CLASS_C_DEC:: get_resize_policy() const { return *this; } 8/ext/pb_ds/detail/cc_hash_table_map_/find_store_hash_fn_imps.hpp000064400000003363152526447520021203 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/find_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s find related functions, * when the hash value is stored. */ 8/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp000064400000006047152526447530017002 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/info_fn_imps.hpp * Contains implementations of cc_ht_map_'s entire container info related * functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_num_used_e; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return m_entry_allocator.max_size(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (size() == 0); } PB_DS_CLASS_T_DEC template bool PB_DS_CLASS_C_DEC:: operator==(const Other_HT_Map_Type& other) const { return cmp_with_other(other); } PB_DS_CLASS_T_DEC template bool PB_DS_CLASS_C_DEC:: cmp_with_other(const Other_Map_Type& other) const { if (size() != other.size()) return false; for (typename Other_Map_Type::const_iterator it = other.begin(); it != other.end(); ++it) { key_const_reference r_key =(key_const_reference)PB_DS_V2F(*it); mapped_const_pointer p_mapped_value = const_cast(*this). find_key_pointer(r_key, traits_base::m_store_extra_indicator); if (p_mapped_value == 0) return false; #ifdef PB_DS_DATA_TRUE_INDICATOR if (p_mapped_value->second != it->second) return false; #endif } return true; } PB_DS_CLASS_T_DEC template bool PB_DS_CLASS_C_DEC:: operator!=(const Other_HT_Map_Type& other) const { return !operator==(other); } 8/ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp000064400000004665152526447530016773 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/find_fn_imps.hpp * Contains implementations of cc_ht_map_'s find related functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) return find_key_pointer(r_key, traits_base::m_store_extra_indicator); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) return const_cast(*this).find_key_pointer(r_key, traits_base::m_store_extra_indicator); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find_end() { return 0; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find_end() const { return 0; } 8/ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp000064400000005150152526447530020055 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/iterators_fn_imps.hpp * Contains implementations of cc_ht_map_'s iterators related functions, e.g., * begin(). */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC::s_end_it; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC::s_const_end_it; PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { pointer p_value; std::pair pos; get_start_it_state(p_value, pos); return iterator(p_value, pos, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return s_end_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { pointer p_value; std::pair pos; get_start_it_state(p_value, pos); return const_iterator(p_value, pos, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return s_const_end_it; } 8/ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp000064400000005612152526447530020240 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/entry_list_fn_imps.hpp * Contains implementations of cc_ht_map_'s entry-list related functions. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: deallocate_links_in_list(entry_pointer p_e) { while (p_e != 0) { entry_pointer p_dealloc_e = p_e; p_e = p_e->m_p_next; s_entry_allocator.deallocate(p_dealloc_e, 1); } } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: get_entry(const_reference r_val, true_type) { // Following line might throw an exception. entry_pointer p_e = s_entry_allocator.allocate(1); // Following lines* cannot* throw an exception. new (&p_e->m_value) value_type(r_val); return p_e; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: get_entry(const_reference r_val, false_type) { // Following line might throw an exception. entry_pointer p_e = s_entry_allocator.allocate(1); cond_dealtor_t cond(p_e); // Following lines might throw an exception. new (&p_e->m_value) value_type(r_val); cond.set_no_action(); return p_e; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rels_entry(entry_pointer p_e) { // The following lines cannot throw exceptions (unless if key-data dtors do). p_e->m_value.~value_type(); s_entry_allocator.deallocate(p_e, 1); } 8/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp000064400000004402152526447530025122 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: constructor_insert_new_imp(const_reference r_val, size_type pos, true_type) { // Following lines might throw an exception. entry_pointer p = get_entry(r_val, traits_base::s_no_throw_copies_indicator); // At this point no exceptions can be thrown. p->m_p_next = m_entries[pos]; p->m_hash = ranged_hash_fn_base::operator()((key_const_reference)(PB_DS_V2F(p->m_value))).second; m_entries[pos] = p; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(r_key);) } 8/ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp000064400000005205152526447530017130 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/debug_fn_imps.hpp * Contains implementations of cc_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { debug_base::check_size(m_num_used_e, __file, __line); assert_entry_pointer_array_valid(m_entries, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_pointer_array_valid(const entry_pointer_array a_p_entries, const char* __file, int __line) const { size_type iterated_num_used_e = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { entry_pointer p_e = a_p_entries[pos]; while (p_e != 0) { ++iterated_num_used_e; assert_entry_pointer_valid(p_e, traits_base::m_store_extra_indicator, __file, __line); p_e = p_e->m_p_next; } } PB_DS_DEBUG_VERIFY(iterated_num_used_e == m_num_used_e); } #include #include #endif 8/ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp000064400000003550152526447530017347 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/insert_fn_imps.hpp * Contains implementations of cc_ht_map_'s insert related functions. */ #include #include 8/ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp000064400000006255152526447530017147 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/erase_fn_imps.hpp * Contains implementations of cc_ht_map_'s erase related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: erase_entry_pointer(entry_pointer& r_p_e) { _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(r_p_e->m_value))); entry_pointer p_e = r_p_e; r_p_e = r_p_e->m_p_next; rels_entry(p_e); _GLIBCXX_DEBUG_ASSERT(m_num_used_e > 0); resize_base::notify_erased(--m_num_used_e); } PB_DS_CLASS_T_DEC template inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { size_type num_ersd = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { while (m_entries[pos] != 0 && pred(m_entries[pos]->m_value)) { ++num_ersd; entry_pointer p_next_e = m_entries[pos]->m_p_next; erase_entry_pointer(m_entries[pos]); m_entries[pos] = p_next_e; } entry_pointer p_e = m_entries[pos]; while (p_e != 0 && p_e->m_p_next != 0) { if (pred(p_e->m_p_next->m_value)) { ++num_ersd; erase_entry_pointer(p_e->m_p_next); } else p_e = p_e->m_p_next; } } do_resize_if_needed_no_throw(); return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { for (size_type pos = 0; pos < m_num_e; ++pos) while (m_entries[pos] != 0) erase_entry_pointer(m_entries[pos]); do_resize_if_needed_no_throw(); resize_base::notify_cleared(); } #include #include 8/ext/pb_ds/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp000064400000003720152526447530022043 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_pointer_valid(const entry_pointer p, false_type, const char* __file, int __line) const { debug_base::check_key_exists(PB_DS_V2F(p->m_value), __file, __line); } #endif 8/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp000064400000004075152526447530017020 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/size_fn_imps.hpp * Contains implementations of cc_ht_map_'s entire container size related * functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_num_used_e; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (size() == 0); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_entry_allocator.max_size(); } 8/ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp000064400000004342152526447530021563 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/resize_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s resize related functions, when the * hash value is stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: resize_imp_no_exceptions_reassign_pointer(entry_pointer p_e, entry_pointer_array a_p_entries_resized, true_type) { const comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash); entry_pointer const p_next_e = p_e->m_p_next; p_e->m_p_next = a_p_entries_resized[pos_hash_pair.first]; a_p_entries_resized[pos_hash_pair.first] = p_e; return p_next_e; } 8/ext/pb_ds/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp000064400000005162152526447530021567 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/insert_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s insert related functions, * when the hash value is stored. */ PB_DS_CLASS_T_DEC inline std::pair PB_DS_CLASS_C_DEC:: insert_imp(const_reference r_val, true_type) { PB_DS_ASSERT_VALID((*this)) key_const_reference key = PB_DS_V2F(r_val); comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(key); entry_pointer p_e = m_entries[pos_hash_pair.first]; resize_base::notify_insert_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, key, pos_hash_pair.second)) { resize_base::notify_insert_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_insert_search_end(); if (p_e != 0) { PB_DS_CHECK_KEY_EXISTS(key) return std::make_pair(&p_e->m_value, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) return std::make_pair(insert_new_imp(r_val, pos_hash_pair), true); } 8/ext/pb_ds/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp000064400000004144152526447530021350 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/debug_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_pointer_valid(const entry_pointer p_e, true_type, const char* __file, int __line) const { debug_base::check_key_exists(PB_DS_V2F(p_e->m_value), __file, __line); comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value)); PB_DS_DEBUG_VERIFY(p_e->m_hash == pos_hash_pair.second); } #endif 8/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp000064400000004262152526447530025622 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: constructor_insert_new_imp(mapped_const_reference r_val, size_type pos, false_type) { // Following lines might throw an exception. entry_pointer p = get_entry(r_val, traits_base::s_no_throw_copies_indicator); // At this point no exceptions can be thrown. p->m_p_next = m_entries[pos]; m_entries[pos] = p; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(r_key);) } 8/ext/pb_ds/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp000064400000006231152526447530021360 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/erase_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s erase related functions, * when the hash value is stored. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase_in_pos_imp(key_const_reference r_key, const comp_hash& r_pos_hash_pair) { PB_DS_ASSERT_VALID((*this)) entry_pointer p_e = m_entries[r_pos_hash_pair.first]; resize_base::notify_erase_search_start(); if (p_e == 0) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) PB_DS_ASSERT_VALID((*this)) return false; } if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, r_key, r_pos_hash_pair.second)) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) erase_entry_pointer(m_entries[r_pos_hash_pair.first]); do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return true; } while (true) { entry_pointer p_next_e = p_e->m_p_next; if (p_next_e == 0) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) PB_DS_ASSERT_VALID((*this)) return false; } if (hash_eq_fn_base::operator()(PB_DS_V2F(p_next_e->m_value), p_next_e->m_hash, r_key, r_pos_hash_pair.second)) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) erase_entry_pointer(p_e->m_p_next); do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return true; } resize_base::notify_erase_search_collision(); p_e = p_next_e; } } 8/ext/pb_ds/detail/cc_hash_table_map_/cmp_fn_imps.hpp000064400000005315152526447530016623 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/cmp_fn_imps.hpp * Contains implementations of cc_ht_map_'s entire container comparison related * functions. */ PB_DS_CLASS_T_DEC template bool PB_DS_CLASS_C_DEC:: operator==(const Other_HT_Map_Type& other) const { return cmp_with_other(other); } PB_DS_CLASS_T_DEC template bool PB_DS_CLASS_C_DEC:: cmp_with_other(const Other_Map_Type& other) const { if (size() != other.size()) return false; for (typename Other_Map_Type::const_iterator it = other.begin(); it != other.end(); ++it) { key_const_reference r_key = key_const_reference(PB_DS_V2F(*it)); mapped_const_pointer p_mapped_value = const_cast(*this). find_key_pointer(r_key, traits_base::m_store_extra_indicator); if (p_mapped_value == 0) return false; #ifdef PB_DS_DATA_TRUE_INDICATOR if (p_mapped_value->second != it->second) return false; #endif } return true; } PB_DS_CLASS_T_DEC template bool PB_DS_CLASS_C_DEC:: operator!=(const Other_HT_Map_Type& other) const { return !operator==(other); } 8/ext/pb_ds/priority_queue.hpp000064400000012576152526447530012430 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file priority_queue.hpp * Contains priority_queues. */ #ifndef PB_DS_PRIORITY_QUEUE_HPP #define PB_DS_PRIORITY_QUEUE_HPP #include #include #include #include namespace __gnu_pbds { /** * @defgroup heap-based Heap-Based * @ingroup containers-pbds * @{ */ /** * @defgroup heap-detail Base and Policy Classes * @ingroup heap-based */ /** * A priority queue composed of one specific heap policy. * * @tparam _Tv Value type. * @tparam Cmp_Fn Comparison functor. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam _Alloc Allocator type. * * Base is dispatched at compile time via Tag, from the following * choices: binary_heap_tag, binomial_heap_tag, pairing_heap_tag, * rc_binomial_heap_tag, thin_heap_tag * * Base choices are: detail::binary_heap, detail::binomial_heap, * detail::pairing_heap, detail::rc_binomial_heap, * detail::thin_heap. */ template, typename Tag = pairing_heap_tag, typename _Alloc = std::allocator > class priority_queue : public detail::container_base_dispatch<_Tv, Cmp_Fn, _Alloc, Tag>::type { public: typedef _Tv value_type; typedef Cmp_Fn cmp_fn; typedef Tag container_category; typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef typename allocator_type::difference_type difference_type; private: typedef typename detail::container_base_dispatch<_Tv, Cmp_Fn, _Alloc, Tag>::type base_type; typedef typename _Alloc::template rebind<_Tv> __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; priority_queue() { } /// Constructor taking some policy objects. r_cmp_fn will be /// copied by the Cmp_Fn object of the container object. priority_queue(const cmp_fn& r_cmp_fn) : base_type(r_cmp_fn) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template priority_queue(It first_it, It last_it) { base_type::copy_from_range(first_it, last_it); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_cmp_fn /// will be copied by the cmp_fn object of the container object. template priority_queue(It first_it, It last_it, const cmp_fn& r_cmp_fn) : base_type(r_cmp_fn) { base_type::copy_from_range(first_it, last_it); } priority_queue(const priority_queue& other) : base_type((const base_type& )other) { } virtual ~priority_queue() { } priority_queue& operator=(const priority_queue& other) { if (this != &other) { priority_queue tmp(other); swap(tmp); } return *this; } void swap(priority_queue& other) { base_type::swap(other); } }; } // namespace __gnu_pbds //@} heap-based #endif 8/ext/pb_ds/trie_policy.hpp000064400000027701152526447530011661 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy.hpp * Contains trie-related policies. */ #ifndef PB_DS_TRIE_POLICY_HPP #define PB_DS_TRIE_POLICY_HPP #include #include #include #include namespace __gnu_pbds { #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ trie_string_access_traits /** * Element access traits for string types. * * @tparam String String type. * @tparam Min_E_Val Minimal element value. * @tparam Max_E_Val Maximum element value. * @tparam Reverse Reverse iteration should be used. * Default: false. * @tparam _Alloc Allocator type. */ template::__min, typename String::value_type Max_E_Val = detail::__numeric_traits::__max, bool Reverse = false, typename _Alloc = std::allocator > struct trie_string_access_traits { public: typedef typename _Alloc::size_type size_type; typedef String key_type; typedef typename _Alloc::template rebind __rebind_k; typedef typename __rebind_k::other::const_reference key_const_reference; enum { reverse = Reverse }; /// Element const iterator type. typedef typename detail::__conditional_type::__type const_iterator; /// Element type. typedef typename std::iterator_traits::value_type e_type; enum { min_e_val = Min_E_Val, max_e_val = Max_E_Val, max_size = max_e_val - min_e_val + 1 }; PB_DS_STATIC_ASSERT(min_max_size, max_size >= 2); /// Returns a const_iterator to the first element of /// key_const_reference agumnet. inline static const_iterator begin(key_const_reference); /// Returns a const_iterator to the after-last element of /// key_const_reference argument. inline static const_iterator end(key_const_reference); /// Maps an element to a position. inline static size_type e_pos(e_type e); private: inline static const_iterator begin_imp(key_const_reference, detail::false_type); inline static const_iterator begin_imp(key_const_reference, detail::true_type); inline static const_iterator end_imp(key_const_reference, detail::false_type); inline static const_iterator end_imp(key_const_reference, detail::true_type); static detail::integral_constant s_rev_ind; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ trie_prefix_search_node_update #define PB_DS_TRIE_POLICY_BASE \ detail::trie_policy_base /// A node updator that allows tries to be searched for the range of /// values that match a certain prefix. template class trie_prefix_search_node_update : private PB_DS_TRIE_POLICY_BASE { private: typedef PB_DS_TRIE_POLICY_BASE base_type; public: typedef typename base_type::key_type key_type; typedef typename base_type::key_const_reference key_const_reference; /// Element access traits. typedef _ATraits access_traits; /// Const element iterator. typedef typename access_traits::const_iterator a_const_iterator; /// _Alloc type. typedef _Alloc allocator_type; /// Size type. typedef typename allocator_type::size_type size_type; typedef null_type metadata_type; typedef Node_Itr node_iterator; typedef Node_CItr node_const_iterator; typedef typename node_iterator::value_type iterator; typedef typename node_const_iterator::value_type const_iterator; /// Finds the const iterator range corresponding to all values /// whose prefixes match r_key. std::pair prefix_range(key_const_reference) const; /// Finds the iterator range corresponding to all values whose /// prefixes match r_key. std::pair prefix_range(key_const_reference); /// Finds the const iterator range corresponding to all values /// whose prefixes match [b, e). std::pair prefix_range(a_const_iterator, a_const_iterator) const; /// Finds the iterator range corresponding to all values whose /// prefixes match [b, e). std::pair prefix_range(a_const_iterator, a_const_iterator); protected: /// Called to update a node's metadata. inline void operator()(node_iterator node_it, node_const_iterator end_nd_it) const; private: node_iterator next_child(node_iterator, a_const_iterator, a_const_iterator, node_iterator, const access_traits&); /// Returns the const iterator associated with the just-after last element. virtual const_iterator end() const = 0; /// Returns the iterator associated with the just-after last element. virtual iterator end() = 0; /// Returns the node_const_iterator associated with the trie's root node. virtual node_const_iterator node_begin() const = 0; /// Returns the node_iterator associated with the trie's root node. virtual node_iterator node_begin() = 0; /// Returns the node_const_iterator associated with a just-after leaf node. virtual node_const_iterator node_end() const = 0; /// Returns the node_iterator associated with a just-after leaf node. virtual node_iterator node_end() = 0; /// Access to the cmp_fn object. virtual const access_traits& get_access_traits() const = 0; }; #include #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_C_DEC \ trie_order_statistics_node_update /// Functor updating ranks of entrees. template class trie_order_statistics_node_update : private PB_DS_TRIE_POLICY_BASE { private: typedef PB_DS_TRIE_POLICY_BASE base_type; public: typedef _ATraits access_traits; typedef typename access_traits::const_iterator a_const_iterator; typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef typename base_type::key_type key_type; typedef typename base_type::key_const_reference key_const_reference; typedef size_type metadata_type; typedef Node_CItr node_const_iterator; typedef Node_Itr node_iterator; typedef typename node_const_iterator::value_type const_iterator; typedef typename node_iterator::value_type iterator; /// Finds an entry by __order. Returns a const_iterator to the /// entry with the __order order, or a const_iterator to the /// container object's end if order is at least the size of the /// container object. inline const_iterator find_by_order(size_type) const; /// Finds an entry by __order. Returns an iterator to the entry /// with the __order order, or an iterator to the container /// object's end if order is at least the size of the container /// object. inline iterator find_by_order(size_type); /// Returns the order of a key within a sequence. For exapmle, if /// r_key is the smallest key, this method will return 0; if r_key /// is a key between the smallest and next key, this method will /// return 1; if r_key is a key larger than the largest key, this /// method will return the size of r_c. inline size_type order_of_key(key_const_reference) const; /// Returns the order of a prefix within a sequence. For exapmle, /// if [b, e] is the smallest prefix, this method will return 0; if /// r_key is a key between the smallest and next key, this method /// will return 1; if r_key is a key larger than the largest key, /// this method will return the size of r_c. inline size_type order_of_prefix(a_const_iterator, a_const_iterator) const; protected: /// Updates the rank of a node through a node_iterator node_it; /// end_nd_it is the end node iterator. inline void operator()(node_iterator, node_const_iterator) const; private: typedef typename base_type::const_reference const_reference; typedef typename base_type::const_pointer const_pointer; typedef typename _Alloc::template rebind __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef typename __rebind_ma::const_reference metadata_const_reference; typedef typename __rebind_ma::reference metadata_reference; /// Returns true if the container is empty. virtual bool empty() const = 0; /// Returns the iterator associated with the trie's first element. virtual iterator begin() = 0; /// Returns the iterator associated with the trie's /// just-after-last element. virtual iterator end() = 0; /// Returns the node_const_iterator associated with the trie's root node. virtual node_const_iterator node_begin() const = 0; /// Returns the node_iterator associated with the trie's root node. virtual node_iterator node_begin() = 0; /// Returns the node_const_iterator associated with a just-after /// leaf node. virtual node_const_iterator node_end() const = 0; /// Returns the node_iterator associated with a just-after leaf node. virtual node_iterator node_end() = 0; /// Access to the cmp_fn object. virtual access_traits& get_access_traits() = 0; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_TRIE_POLICY_BASE } // namespace __gnu_pbds #endif 8/ext/pb_ds/hash_policy.hpp000064400000040657152526447530011646 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_policy.hpp * Contains hash-related policies. */ #ifndef PB_DS_HASH_POLICY_HPP #define PB_DS_HASH_POLICY_HPP #include #include #include #include #include #include #include #include #include namespace __gnu_pbds { #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC linear_probe_fn /// A probe sequence policy using fixed increments. template class linear_probe_fn { public: typedef Size_Type size_type; void swap(PB_DS_CLASS_C_DEC& other); protected: /// Returns the i-th offset from the hash value. inline size_type operator()(size_type i) const; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC quadratic_probe_fn /// A probe sequence policy using square increments. template class quadratic_probe_fn { public: typedef Size_Type size_type; void swap(PB_DS_CLASS_C_DEC& other); protected: /// Returns the i-th offset from the hash value. inline size_type operator()(size_type i) const; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC direct_mask_range_hashing /// A mask range-hashing class (uses a bitmask). template class direct_mask_range_hashing : public detail::mask_based_range_hashing { private: typedef detail::mask_based_range_hashing mask_based_base; public: typedef Size_Type size_type; void swap(PB_DS_CLASS_C_DEC& other); protected: void notify_resized(size_type size); /// Transforms the __hash value hash into a ranged-hash value /// (using a bit-mask). inline size_type operator()(size_type hash) const; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC direct_mod_range_hashing /// A mod range-hashing class (uses the modulo function). template class direct_mod_range_hashing : public detail::mod_based_range_hashing { public: typedef Size_Type size_type; void swap(PB_DS_CLASS_C_DEC& other); protected: void notify_resized(size_type size); /// Transforms the __hash value hash into a ranged-hash value /// (using a modulo operation). inline size_type operator()(size_type hash) const; private: typedef detail::mod_based_range_hashing mod_based_base; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC hash_load_check_resize_trigger #define PB_DS_SIZE_BASE_C_DEC detail::hash_load_check_resize_trigger_size_base /// A resize trigger policy based on a load check. It keeps the /// load factor between some load factors load_min and load_max. template class hash_load_check_resize_trigger : private PB_DS_SIZE_BASE_C_DEC { public: typedef Size_Type size_type; enum { /// Specifies whether the load factor can be accessed /// externally. The two options have different trade-offs in /// terms of flexibility, genericity, and encapsulation. external_load_access = External_Load_Access }; /// Default constructor, or constructor taking load_min and /// load_max load factors between which this policy will keep the /// actual load. hash_load_check_resize_trigger(float load_min = 0.125, float load_max = 0.5); void swap(hash_load_check_resize_trigger& other); virtual ~hash_load_check_resize_trigger(); /// Returns a pair of the minimal and maximal loads, respectively. inline std::pair get_loads() const; /// Sets the loads through a pair of the minimal and maximal /// loads, respectively. void set_loads(std::pair load_pair); protected: inline void notify_insert_search_start(); inline void notify_insert_search_collision(); inline void notify_insert_search_end(); inline void notify_find_search_start(); inline void notify_find_search_collision(); inline void notify_find_search_end(); inline void notify_erase_search_start(); inline void notify_erase_search_collision(); inline void notify_erase_search_end(); /// Notifies an element was inserted. The total number of entries /// in the table is num_entries. inline void notify_inserted(size_type num_entries); inline void notify_erased(size_type num_entries); /// Notifies the table was cleared. void notify_cleared(); /// Notifies the table was resized as a result of this object's /// signifying that a resize is needed. void notify_resized(size_type new_size); void notify_externally_resized(size_type new_size); inline bool is_resize_needed() const; inline bool is_grow_needed(size_type size, size_type num_entries) const; private: virtual void do_resize(size_type new_size); typedef PB_DS_SIZE_BASE_C_DEC size_base; #ifdef _GLIBCXX_DEBUG void assert_valid(const char* file, int line) const; #endif float m_load_min; float m_load_max; size_type m_next_shrink_size; size_type m_next_grow_size; bool m_resize_needed; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_SIZE_BASE_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC cc_hash_max_collision_check_resize_trigger /// A resize trigger policy based on collision checks. It keeps the /// simulated load factor lower than some given load factor. template class cc_hash_max_collision_check_resize_trigger { public: typedef Size_Type size_type; enum { /// Specifies whether the load factor can be accessed /// externally. The two options have different trade-offs in /// terms of flexibility, genericity, and encapsulation. external_load_access = External_Load_Access }; /// Default constructor, or constructor taking load, a __load /// factor which it will attempt to maintain. cc_hash_max_collision_check_resize_trigger(float load = 0.5); void swap(PB_DS_CLASS_C_DEC& other); /// Returns the current load. inline float get_load() const; /// Sets the load; does not resize the container. void set_load(float load); protected: /// Notifies an insert search started. inline void notify_insert_search_start(); /// Notifies a search encountered a collision. inline void notify_insert_search_collision(); /// Notifies a search ended. inline void notify_insert_search_end(); /// Notifies a find search started. inline void notify_find_search_start(); /// Notifies a search encountered a collision. inline void notify_find_search_collision(); /// Notifies a search ended. inline void notify_find_search_end(); /// Notifies an erase search started. inline void notify_erase_search_start(); /// Notifies a search encountered a collision. inline void notify_erase_search_collision(); /// Notifies a search ended. inline void notify_erase_search_end(); /// Notifies an element was inserted. inline void notify_inserted(size_type num_entries); /// Notifies an element was erased. inline void notify_erased(size_type num_entries); /// Notifies the table was cleared. void notify_cleared(); /// Notifies the table was resized as a result of this object's /// signifying that a resize is needed. void notify_resized(size_type new_size); /// Notifies the table was resized externally. void notify_externally_resized(size_type new_size); /// Queries whether a resize is needed. inline bool is_resize_needed() const; /// Queries whether a grow is needed. This method is called only /// if this object indicated is needed. inline bool is_grow_needed(size_type size, size_type num_entries) const; private: void calc_max_num_coll(); inline void calc_resize_needed(); float m_load; size_type m_size; size_type m_num_col; size_type m_max_col; bool m_resize_needed; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC hash_exponential_size_policy /// A size policy whose sequence of sizes form an exponential /// sequence (typically powers of 2. template class hash_exponential_size_policy { public: typedef Size_Type size_type; /// Default constructor, or onstructor taking a start_size, or /// constructor taking a start size and grow_factor. The policy /// will use the sequence of sizes start_size, start_size* /// grow_factor, start_size* grow_factor^2, ... hash_exponential_size_policy(size_type start_size = 8, size_type grow_factor = 2); void swap(PB_DS_CLASS_C_DEC& other); protected: size_type get_nearest_larger_size(size_type size) const; size_type get_nearest_smaller_size(size_type size) const; private: size_type m_start_size; size_type m_grow_factor; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC #define PB_DS_CLASS_C_DEC hash_prime_size_policy /// A size policy whose sequence of sizes form a nearly-exponential /// sequence of primes. class hash_prime_size_policy { public: /// Size type. typedef std::size_t size_type; /// Default constructor, or onstructor taking a start_size The /// policy will use the sequence of sizes approximately /// start_size, start_size* 2, start_size* 2^2, ... hash_prime_size_policy(size_type start_size = 8); inline void swap(PB_DS_CLASS_C_DEC& other); protected: size_type get_nearest_larger_size(size_type size) const; size_type get_nearest_smaller_size(size_type size) const; private: size_type m_start_size; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template #define PB_DS_CLASS_C_DEC hash_standard_resize_policy /// A resize policy which delegates operations to size and trigger policies. template, typename Trigger_Policy = hash_load_check_resize_trigger<>, bool External_Size_Access = false, typename Size_Type = std::size_t> class hash_standard_resize_policy : public Size_Policy, public Trigger_Policy { public: typedef Size_Type size_type; typedef Trigger_Policy trigger_policy; typedef Size_Policy size_policy; enum { external_size_access = External_Size_Access }; /// Default constructor. hash_standard_resize_policy(); /// constructor taking some policies r_size_policy will be copied /// by the Size_Policy object of this object. hash_standard_resize_policy(const Size_Policy& r_size_policy); /// constructor taking some policies. r_size_policy will be /// copied by the Size_Policy object of this /// object. r_trigger_policy will be copied by the Trigger_Policy /// object of this object. hash_standard_resize_policy(const Size_Policy& r_size_policy, const Trigger_Policy& r_trigger_policy); virtual ~hash_standard_resize_policy(); inline void swap(PB_DS_CLASS_C_DEC& other); /// Access to the Size_Policy object used. Size_Policy& get_size_policy(); /// Const access to the Size_Policy object used. const Size_Policy& get_size_policy() const; /// Access to the Trigger_Policy object used. Trigger_Policy& get_trigger_policy(); /// Access to the Trigger_Policy object used. const Trigger_Policy& get_trigger_policy() const; /// Returns the actual size of the container. inline size_type get_actual_size() const; /// Resizes the container to suggested_new_size, a suggested size /// (the actual size will be determined by the Size_Policy /// object). void resize(size_type suggested_new_size); protected: inline void notify_insert_search_start(); inline void notify_insert_search_collision(); inline void notify_insert_search_end(); inline void notify_find_search_start(); inline void notify_find_search_collision(); inline void notify_find_search_end(); inline void notify_erase_search_start(); inline void notify_erase_search_collision(); inline void notify_erase_search_end(); inline void notify_inserted(size_type num_e); inline void notify_erased(size_type num_e); void notify_cleared(); void notify_resized(size_type new_size); inline bool is_resize_needed() const; /// Queries what the new size should be, when the container is /// resized naturally. The current __size of the container is /// size, and the number of used entries within the container is /// num_used_e. size_type get_new_size(size_type size, size_type num_used_e) const; private: /// Resizes to new_size. virtual void do_resize(size_type new_size); typedef Trigger_Policy trigger_policy_base; typedef Size_Policy size_policy_base; size_type m_size; }; #include #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace __gnu_pbds #endif 8/ext/pb_ds/assoc_container.hpp000064400000072636152526447530012520 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file assoc_container.hpp * Contains associative containers. */ #ifndef PB_DS_ASSOC_CNTNR_HPP #define PB_DS_ASSOC_CNTNR_HPP #include #include #include #include #include #include namespace __gnu_pbds { /** * @defgroup containers-pbds Containers * @ingroup pbds * @{ */ /** * @defgroup hash-based Hash-Based * @ingroup containers-pbds * @{ */ #define PB_DS_HASH_BASE \ detail::container_base_dispatch >::type, Policy_Tl>::type>::type /** * @defgroup hash-detail Base and Policy Classes * @ingroup hash-based */ /** * A hashed container abstraction. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Hash_Fn Hashing functor. * @tparam Eq_Fn Equal functor. * @tparam Resize_Policy Resizes hash. * @tparam Store_Hash Indicates whether the hash value * will be stored along with each key. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam Policy_TL Policy typelist. * @tparam _Alloc Allocator type. * * Base is dispatched at compile time via Tag, from the following * choices: cc_hash_tag, gp_hash_tag, and descendants of basic_hash_tag. * * Base choices are: detail::cc_ht_map, detail::gp_ht_map */ template class basic_hash_table : public PB_DS_HASH_BASE { private: typedef typename PB_DS_HASH_BASE base_type; public: virtual ~basic_hash_table() { } protected: basic_hash_table() { } basic_hash_table(const basic_hash_table& other) : base_type((const base_type&)other) { } template basic_hash_table(T0 t0) : base_type(t0) { } template basic_hash_table(T0 t0, T1 t1) : base_type(t0, t1) { } template basic_hash_table(T0 t0, T1 t1, T2 t2) : base_type(t0, t1, t2) { } template basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3) : base_type(t0, t1, t2, t3) { } template basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) : base_type(t0, t1, t2, t3, t4) { } template basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) : base_type(t0, t1, t2, t3, t4, t5) { } template basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) : base_type(t0, t1, t2, t3, t4, t5, t6) { } template basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) : base_type(t0, t1, t2, t3, t4, t5, t6, t7) { } template basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) : base_type(t0, t1, t2, t3, t4, t5, t6, t7, t8) { } private: basic_hash_table& operator=(const base_type&); }; #undef PB_DS_HASH_BASE #define PB_DS_CC_HASH_BASE \ basic_hash_table::type, _Alloc> /** * A collision-chaining hash-based associative container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Hash_Fn Hashing functor. * @tparam Eq_Fn Equal functor. * @tparam Comb_Hash_Fn Combining hash functor. * If Hash_Fn is not null_type, then this * is the ranged-hash functor; otherwise, * this is the range-hashing functor. * XXX(See Design::Hash-Based Containers::Hash Policies.) * @tparam Resize_Policy Resizes hash. * @tparam Store_Hash Indicates whether the hash value * will be stored along with each key. * If Hash_Fn is null_type, then the * container will not compile if this * value is true * @tparam _Alloc Allocator type. * * Base tag choices are: cc_hash_tag. * * Base is basic_hash_table. */ template::type, typename Eq_Fn = typename detail::default_eq_fn::type, typename Comb_Hash_Fn = detail::default_comb_hash_fn::type, typename Resize_Policy = typename detail::default_resize_policy::type, bool Store_Hash = detail::default_store_hash, typename _Alloc = std::allocator > class cc_hash_table : public PB_DS_CC_HASH_BASE { private: typedef PB_DS_CC_HASH_BASE base_type; public: typedef cc_hash_tag container_category; typedef Hash_Fn hash_fn; typedef Eq_Fn eq_fn; typedef Resize_Policy resize_policy; typedef Comb_Hash_Fn comb_hash_fn; /// Default constructor. cc_hash_table() { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the Hash_Fn object of the container object. cc_hash_table(const hash_fn& h) : base_type(h) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, and /// r_eq_fn will be copied by the eq_fn object of the container /// object. cc_hash_table(const hash_fn& h, const eq_fn& e) : base_type(h, e) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// and r_comb_hash_fn will be copied by the comb_hash_fn object /// of the container object. cc_hash_table(const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch) : base_type(h, e, ch) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// r_comb_hash_fn will be copied by the comb_hash_fn object of /// the container object, and r_resize_policy will be copied by /// the resize_policy object of the container object. cc_hash_table(const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch, const resize_policy& rp) : base_type(h, e, ch, rp) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template cc_hash_table(It first, It last) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. template cc_hash_table(It first, It last, const hash_fn& h) : base_type(h) { this->copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// and r_eq_fn will be copied by the eq_fn object of the /// container object. template cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e) : base_type(h, e) { this->copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, and r_comb_hash_fn will be copied by the comb_hash_fn /// object of the container object. template cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch) : base_type(h, e, ch) { this->copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, r_comb_hash_fn will be copied by the comb_hash_fn /// object of the container object, and r_resize_policy will be /// copied by the resize_policy object of the container object. template cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch, const resize_policy& rp) : base_type(h, e, ch, rp) { this->copy_from_range(first, last); } cc_hash_table(const cc_hash_table& other) : base_type((const base_type&)other) { } virtual ~cc_hash_table() { } cc_hash_table& operator=(const cc_hash_table& other) { if (this != &other) { cc_hash_table tmp(other); swap(tmp); } return *this; } void swap(cc_hash_table& other) { base_type::swap(other); } }; #undef PB_DS_CC_HASH_BASE #define PB_DS_GP_HASH_BASE \ basic_hash_table::type, _Alloc> /** * A general-probing hash-based associative container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Hash_Fn Hashing functor. * @tparam Eq_Fn Equal functor. * @tparam Comb_Probe_Fn Combining probe functor. * If Hash_Fn is not null_type, then this * is the ranged-probe functor; otherwise, * this is the range-hashing functor. * XXX See Design::Hash-Based Containers::Hash Policies. * @tparam Probe_Fn Probe functor. * @tparam Resize_Policy Resizes hash. * @tparam Store_Hash Indicates whether the hash value * will be stored along with each key. * If Hash_Fn is null_type, then the * container will not compile if this * value is true * @tparam _Alloc Allocator type. * * Base tag choices are: gp_hash_tag. * * Base is basic_hash_table. */ template::type, typename Eq_Fn = typename detail::default_eq_fn::type, typename Comb_Probe_Fn = detail::default_comb_hash_fn::type, typename Probe_Fn = typename detail::default_probe_fn::type, typename Resize_Policy = typename detail::default_resize_policy::type, bool Store_Hash = detail::default_store_hash, typename _Alloc = std::allocator > class gp_hash_table : public PB_DS_GP_HASH_BASE { private: typedef PB_DS_GP_HASH_BASE base_type; public: typedef gp_hash_tag container_category; typedef Hash_Fn hash_fn; typedef Eq_Fn eq_fn; typedef Comb_Probe_Fn comb_probe_fn; typedef Probe_Fn probe_fn; typedef Resize_Policy resize_policy; /// Default constructor. gp_hash_table() { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object. gp_hash_table(const hash_fn& h) : base_type(h) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, and /// r_eq_fn will be copied by the eq_fn object of the container /// object. gp_hash_table(const hash_fn& h, const eq_fn& e) : base_type(h, e) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// and r_comb_probe_fn will be copied by the comb_probe_fn object /// of the container object. gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp) : base_type(h, e, cp) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// r_comb_probe_fn will be copied by the comb_probe_fn object of /// the container object, and r_probe_fn will be copied by the /// probe_fn object of the container object. gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, const probe_fn& p) : base_type(h, e, cp, p) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// r_comb_probe_fn will be copied by the comb_probe_fn object of /// the container object, r_probe_fn will be copied by the /// probe_fn object of the container object, and r_resize_policy /// will be copied by the Resize_Policy object of the container /// object. gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, const probe_fn& p, const resize_policy& rp) : base_type(h, e, cp, p, rp) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template gp_hash_table(It first, It last) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object. template gp_hash_table(It first, It last, const hash_fn& h) : base_type(h) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// and r_eq_fn will be copied by the eq_fn object of the /// container object. template gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e) : base_type(h, e) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, and r_comb_probe_fn will be copied by the /// comb_probe_fn object of the container object. template gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp) : base_type(h, e, cp) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, r_comb_probe_fn will be copied by the comb_probe_fn /// object of the container object, and r_probe_fn will be copied /// by the probe_fn object of the container object. template gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, const probe_fn& p) : base_type(h, e, cp, p) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, r_comb_probe_fn will be copied by the comb_probe_fn /// object of the container object, r_probe_fn will be copied by /// the probe_fn object of the container object, and /// r_resize_policy will be copied by the resize_policy object of /// the container object. template gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, const probe_fn& p, const resize_policy& rp) : base_type(h, e, cp, p, rp) { base_type::copy_from_range(first, last); } gp_hash_table(const gp_hash_table& other) : base_type((const base_type&)other) { } virtual ~gp_hash_table() { } gp_hash_table& operator=(const gp_hash_table& other) { if (this != &other) { gp_hash_table tmp(other); swap(tmp); } return *this; } void swap(gp_hash_table& other) { base_type::swap(other); } }; //@} hash-based #undef PB_DS_GP_HASH_BASE /** * @defgroup branch-based Branch-Based * @ingroup containers-pbds * @{ */ #define PB_DS_BRANCH_BASE \ detail::container_base_dispatch::type /** * @defgroup branch-detail Base and Policy Classes * @ingroup branch-based */ /** * A branched, tree-like (tree, trie) container abstraction. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam Node_Update Updates nodes, restores invariants. * @tparam Policy_TL Policy typelist. * @tparam _Alloc Allocator type. * * Base is dispatched at compile time via Tag, from the following * choices: tree_tag, trie_tag, and their descendants. * * Base choices are: detail::ov_tree_map, detail::rb_tree_map, * detail::splay_tree_map, and detail::pat_trie_map. */ template class basic_branch : public PB_DS_BRANCH_BASE { private: typedef typename PB_DS_BRANCH_BASE base_type; public: typedef Node_Update node_update; virtual ~basic_branch() { } protected: basic_branch() { } basic_branch(const basic_branch& other) : base_type((const base_type&)other) { } template basic_branch(T0 t0) : base_type(t0) { } template basic_branch(T0 t0, T1 t1) : base_type(t0, t1) { } template basic_branch(T0 t0, T1 t1, T2 t2) : base_type(t0, t1, t2) { } template basic_branch(T0 t0, T1 t1, T2 t2, T3 t3) : base_type(t0, t1, t2, t3) { } template basic_branch(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) : base_type(t0, t1, t2, t3, t4) { } template basic_branch(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) : base_type(t0, t1, t2, t3, t4, t5) { } template basic_branch(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) : base_type(t0, t1, t2, t3, t4, t5, t6) { } }; #undef PB_DS_BRANCH_BASE #define PB_DS_TREE_NODE_AND_IT_TRAITS \ detail::tree_traits #define PB_DS_TREE_BASE \ basic_branch::type, _Alloc> /** * A tree-based container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Cmp_Fn Comparison functor. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam Node_Update Updates tree internal-nodes, * restores invariants when invalidated. * XXX See design::tree-based-containers::node invariants. * @tparam _Alloc Allocator type. * * Base tag choices are: ov_tree_tag, rb_tree_tag, splay_tree_tag. * * Base is basic_branch. */ template, typename Tag = rb_tree_tag, template class Node_Update = null_node_update, typename _Alloc = std::allocator > class tree : public PB_DS_TREE_BASE { private: typedef PB_DS_TREE_BASE base_type; public: /// Comparison functor type. typedef Cmp_Fn cmp_fn; tree() { } /// Constructor taking some policy objects. r_cmp_fn will be /// copied by the Cmp_Fn object of the container object. tree(const cmp_fn& c) : base_type(c) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template tree(It first, It last) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_cmp_fn /// will be copied by the cmp_fn object of the container object. template tree(It first, It last, const cmp_fn& c) : base_type(c) { base_type::copy_from_range(first, last); } tree(const tree& other) : base_type((const base_type&)other) { } virtual ~tree() { } tree& operator=(const tree& other) { if (this != &other) { tree tmp(other); swap(tmp); } return *this; } void swap(tree& other) { base_type::swap(other); } }; #undef PB_DS_TREE_BASE #undef PB_DS_TREE_NODE_AND_IT_TRAITS #define PB_DS_TRIE_NODE_AND_IT_TRAITS \ detail::trie_traits #define PB_DS_TRIE_BASE \ basic_branch::type, _Alloc> /** * A trie-based container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam _ATraits Element access traits. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam Node_Update Updates trie internal-nodes, * restores invariants when invalidated. * XXX See design::tree-based-containers::node invariants. * @tparam _Alloc Allocator type. * * Base tag choice is pat_trie_tag. * * Base is basic_branch. */ template::type, typename Tag = pat_trie_tag, template class Node_Update = null_node_update, typename _Alloc = std::allocator > class trie : public PB_DS_TRIE_BASE { private: typedef PB_DS_TRIE_BASE base_type; public: /// Element access traits type. typedef _ATraits access_traits; trie() { } /// Constructor taking some policy objects. r_access_traits will /// be copied by the _ATraits object of the container object. trie(const access_traits& t) : base_type(t) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template trie(It first, It last) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. template trie(It first, It last, const access_traits& t) : base_type(t) { base_type::copy_from_range(first, last); } trie(const trie& other) : base_type((const base_type&)other) { } virtual ~trie() { } trie& operator=(const trie& other) { if (this != &other) { trie tmp(other); swap(tmp); } return *this; } void swap(trie& other) { base_type::swap(other); } }; //@} branch-based #undef PB_DS_TRIE_BASE #undef PB_DS_TRIE_NODE_AND_IT_TRAITS /** * @defgroup list-based List-Based * @ingroup containers-pbds * @{ */ #define PB_DS_LU_BASE \ detail::container_base_dispatch::type>::type /** * A list-update based associative container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Eq_Fn Equal functor. * @tparam Update_Policy Update policy, determines when an element * will be moved to the front of the list. * @tparam _Alloc Allocator type. * * Base is detail::lu_map. */ template::type, class Update_Policy = detail::default_update_policy::type, class _Alloc = std::allocator > class list_update : public PB_DS_LU_BASE { private: typedef typename PB_DS_LU_BASE base_type; public: typedef list_update_tag container_category; typedef Eq_Fn eq_fn; typedef Update_Policy update_policy; list_update() { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template list_update(It first, It last) { base_type::copy_from_range(first, last); } list_update(const list_update& other) : base_type((const base_type&)other) { } virtual ~list_update() { } list_update& operator=(const list_update& other) { if (this !=& other) { list_update tmp(other); swap(tmp); } return *this; } void swap(list_update& other) { base_type::swap(other); } }; //@} list-based #undef PB_DS_LU_BASE // @} group containers-pbds } // namespace __gnu_pbds #endif 8/ext/pb_ds/exception.hpp000064400000005654152526447530011340 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file exception.hpp * Contains exception classes. */ #ifndef PB_DS_EXCEPTION_HPP #define PB_DS_EXCEPTION_HPP #include #include #include namespace __gnu_pbds { /** * @defgroup exceptions-pbds Exceptions * @ingroup pbds * @{ */ /// Base class for exceptions. struct container_error : public std::logic_error { container_error() : std::logic_error(__N("__gnu_pbds::container_error")) { } }; /// An entry cannot be inserted into a container object for logical /// reasons (not, e.g., if memory is unabvailable, in which case /// the allocator_type's exception will be thrown). struct insert_error : public container_error { }; /// A join cannot be performed logical reasons (i.e., the ranges of /// the two container objects being joined overlaps. struct join_error : public container_error { }; /// A container cannot be resized. struct resize_error : public container_error { }; inline void __throw_container_error() { _GLIBCXX_THROW_OR_ABORT(container_error()); } inline void __throw_insert_error() { _GLIBCXX_THROW_OR_ABORT(insert_error()); } inline void __throw_join_error() { _GLIBCXX_THROW_OR_ABORT(join_error()); } inline void __throw_resize_error() { _GLIBCXX_THROW_OR_ABORT(resize_error()); } //@} } // namespace __gnu_pbds #endif 8/ext/pb_ds/tag_and_trait.hpp000064400000027754152526447530012147 0ustar00// -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, 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 // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tag_and_trait.hpp * Contains tags and traits, e.g., ones describing underlying * data structures. */ #ifndef PB_DS_TAG_AND_TRAIT_HPP #define PB_DS_TAG_AND_TRAIT_HPP #include #include /** * @namespace __gnu_pbds * @brief GNU extensions for policy-based data structures for public use. */ namespace __gnu_pbds { /** @defgroup pbds Policy-Based Data Structures * @ingroup extensions * * This is a library of policy-based elementary data structures: * associative containers and priority queues. It is designed for * high-performance, flexibility, semantic safety, and conformance * to the corresponding containers in std (except for some points * where it differs by design). * * For details, see: * http://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/index.html * * @{ */ /** * @defgroup tags Tags * @{ */ /// A trivial iterator tag. Signifies that the iterators has none of /// std::iterators's movement abilities. struct trivial_iterator_tag { }; /// Prohibit moving trivial iterators. typedef void trivial_iterator_difference_type; /** * @defgroup invalidation_tags Invalidation Guarantees * @ingroup tags * @{ */ /** * Signifies a basic invalidation guarantee that any iterator, * pointer, or reference to a container object's mapped value type * is valid as long as the container is not modified. */ struct basic_invalidation_guarantee { }; /** * Signifies an invalidation guarantee that includes all those of * its base, and additionally, that any point-type iterator, * pointer, or reference to a container object's mapped value type * is valid as long as its corresponding entry has not be erased, * regardless of modifications to the container object. */ struct point_invalidation_guarantee : public basic_invalidation_guarantee { }; /** * Signifies an invalidation guarantee that includes all those of * its base, and additionally, that any range-type iterator * (including the returns of begin() and end()) is in the correct * relative positions to other range-type iterators as long as its * corresponding entry has not be erased, regardless of * modifications to the container object. */ struct range_invalidation_guarantee : public point_invalidation_guarantee { }; //@} /** * @defgroup ds_tags Data Structure Type * @ingroup tags * @{ */ /// Base data structure tag. struct container_tag { }; /// Basic sequence. struct sequence_tag : public container_tag { }; /// Basic string container, inclusive of strings, ropes, etc. struct string_tag : public sequence_tag { }; /// Basic associative-container. struct associative_tag : public container_tag { }; /// Basic hash structure. struct basic_hash_tag : public associative_tag { }; /// Collision-chaining hash. struct cc_hash_tag : public basic_hash_tag { }; /// General-probing hash. struct gp_hash_tag : public basic_hash_tag { }; /// Basic branch structure. struct basic_branch_tag : public associative_tag { }; /// Basic tree structure. struct tree_tag : public basic_branch_tag { }; /// Red-black tree. struct rb_tree_tag : public tree_tag { }; /// Splay tree. struct splay_tree_tag : public tree_tag { }; /// Ordered-vector tree. struct ov_tree_tag : public tree_tag { }; /// Basic trie structure. struct trie_tag : public basic_branch_tag { }; /// PATRICIA trie. struct pat_trie_tag : public trie_tag { }; /// List-update. struct list_update_tag : public associative_tag { }; /// Basic priority-queue. struct priority_queue_tag : public container_tag { }; /// Pairing-heap. struct pairing_heap_tag : public priority_queue_tag { }; /// Binomial-heap. struct binomial_heap_tag : public priority_queue_tag { }; /// Redundant-counter binomial-heap. struct rc_binomial_heap_tag : public priority_queue_tag { }; /// Binary-heap (array-based). struct binary_heap_tag : public priority_queue_tag { }; /// Thin heap. struct thin_heap_tag : public priority_queue_tag { }; //@} //@} /** * @defgroup traits Traits * @{ */ /** * @brief Represents no type, or absence of type, for template tricks. * * In a mapped-policy, indicates that an associative container is a set. * * In a list-update policy, indicates that each link does not need * metadata. * * In a hash policy, indicates that the combining hash function * is actually a ranged hash function. * * In a probe policy, indicates that the combining probe function * is actually a ranged probe function. */ struct null_type { }; /// A null node updator, indicating that no node updates are required. template struct null_node_update : public null_type { }; /// Primary template, container traits base. template struct container_traits_base; /// Specialization, cc hash. template<> struct container_traits_base { typedef cc_hash_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, gp hash. template<> struct container_traits_base { typedef gp_hash_tag container_category; typedef basic_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, rb tree. template<> struct container_traits_base { typedef rb_tree_tag container_category; typedef range_invalidation_guarantee invalidation_guarantee; enum { order_preserving = true, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = true }; }; /// Specialization, splay tree. template<> struct container_traits_base { typedef splay_tree_tag container_category; typedef range_invalidation_guarantee invalidation_guarantee; enum { order_preserving = true, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = true }; }; /// Specialization, ov tree. template<> struct container_traits_base { typedef ov_tree_tag container_category; typedef basic_invalidation_guarantee invalidation_guarantee; enum { order_preserving = true, erase_can_throw = true, split_join_can_throw = true, reverse_iteration = false }; }; /// Specialization, pat trie. template<> struct container_traits_base { typedef pat_trie_tag container_category; typedef range_invalidation_guarantee invalidation_guarantee; enum { order_preserving = true, erase_can_throw = false, split_join_can_throw = true, reverse_iteration = true }; }; /// Specialization, list update. template<> struct container_traits_base { typedef list_update_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, pairing heap. template<> struct container_traits_base { typedef pairing_heap_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, thin heap. template<> struct container_traits_base { typedef thin_heap_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, binomial heap. template<> struct container_traits_base { typedef binomial_heap_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, rc binomial heap. template<> struct container_traits_base { typedef rc_binomial_heap_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, binary heap. template<> struct container_traits_base { typedef binary_heap_tag container_category; typedef basic_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = true, reverse_iteration = false }; }; /// Container traits. // See Matt Austern for the name, S. Meyers MEFC++ #2, others. template struct container_traits : public container_traits_base { typedef Cntnr container_type; typedef typename Cntnr::container_category container_category; typedef container_traits_base base_type; typedef typename base_type::invalidation_guarantee invalidation_guarantee; enum { /// True only if Cntnr objects guarantee storing keys by order. order_preserving = base_type::order_preserving, /// True only if erasing a key can throw. erase_can_throw = base_type::erase_can_throw, /// True only if split or join operations can throw. split_join_can_throw = base_type::split_join_can_throw, /// True only reverse iterators are supported. reverse_iteration = base_type::reverse_iteration }; }; //@} namespace detail { /// Dispatch mechanism, primary template for associative types. template struct container_base_dispatch; } // namespace detail //@} } // namespace __gnu_pbds #endif 8/ext/algorithm000064400000045532152526447530007452 0ustar00// Algorithm extensions -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file ext/algorithm * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_ALGORITHM #define _EXT_ALGORITHM 1 #pragma GCC system_header #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::ptrdiff_t; using std::min; using std::pair; using std::input_iterator_tag; using std::random_access_iterator_tag; using std::iterator_traits; //-------------------------------------------------- // copy_n (not part of the C++ standard) template pair<_InputIterator, _OutputIterator> __copy_n(_InputIterator __first, _Size __count, _OutputIterator __result, input_iterator_tag) { for ( ; __count > 0; --__count) { *__result = *__first; ++__first; ++__result; } return pair<_InputIterator, _OutputIterator>(__first, __result); } template inline pair<_RAIterator, _OutputIterator> __copy_n(_RAIterator __first, _Size __count, _OutputIterator __result, random_access_iterator_tag) { _RAIterator __last = __first + __count; return pair<_RAIterator, _OutputIterator>(__last, std::copy(__first, __last, __result)); } /** * @brief Copies the range [first,first+count) into [result,result+count). * @param __first An input iterator. * @param __count The number of elements to copy. * @param __result An output iterator. * @return A std::pair composed of first+count and result+count. * * This is an SGI extension. * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). * @ingroup SGIextensions */ template inline pair<_InputIterator, _OutputIterator> copy_n(_InputIterator __first, _Size __count, _OutputIterator __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator>::value_type>) return __gnu_cxx::__copy_n(__first, __count, __result, std::__iterator_category(__first)); } template int __lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { while (__first1 != __last1 && __first2 != __last2) { if (*__first1 < *__first2) return -1; if (*__first2 < *__first1) return 1; ++__first1; ++__first2; } if (__first2 == __last2) return !(__first1 == __last1); else return -1; } inline int __lexicographical_compare_3way(const unsigned char* __first1, const unsigned char* __last1, const unsigned char* __first2, const unsigned char* __last2) { const ptrdiff_t __len1 = __last1 - __first1; const ptrdiff_t __len2 = __last2 - __first2; const int __result = __builtin_memcmp(__first1, __first2, min(__len1, __len2)); return __result != 0 ? __result : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1)); } inline int __lexicographical_compare_3way(const char* __first1, const char* __last1, const char* __first2, const char* __last2) { #if CHAR_MAX == SCHAR_MAX return __lexicographical_compare_3way((const signed char*) __first1, (const signed char*) __last1, (const signed char*) __first2, (const signed char*) __last2); #else return __lexicographical_compare_3way((const unsigned char*) __first1, (const unsigned char*) __last1, (const unsigned char*) __first2, (const unsigned char*) __last2); #endif } /** * @brief @c memcmp on steroids. * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @return An int, as with @c memcmp. * * The return value will be less than zero if the first range is * lexigraphically less than the second, greater than zero * if the second range is lexigraphically less than the * first, and zero otherwise. * This is an SGI extension. * @ingroup SGIextensions */ template int lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); } // count and count_if: this version, whose return type is void, was present // in the HP STL, and is retained as an extension for backward compatibility. template void count(_InputIterator __first, _InputIterator __last, const _Tp& __value, _Size& __n) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_InputIterator>::value_type >) __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) if (*__first == __value) ++__n; } template void count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred, _Size& __n) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) if (__pred(*__first)) ++__n; } // random_sample and random_sample_n (extensions, not part of the standard). /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template _OutputIterator random_sample_n(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __out, const _Distance __n) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); _Distance __remaining = std::distance(__first, __last); _Distance __m = min(__n, __remaining); while (__m > 0) { if ((std::rand() % __remaining) < __m) { *__out = *__first; ++__out; --__m; } --__remaining; ++__first; } return __out; } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template _OutputIterator random_sample_n(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __out, const _Distance __n, _RandomNumberGenerator& __rand) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_function_requires(_UnaryFunctionConcept< _RandomNumberGenerator, _Distance, _Distance>) __glibcxx_requires_valid_range(__first, __last); _Distance __remaining = std::distance(__first, __last); _Distance __m = min(__n, __remaining); while (__m > 0) { if (__rand(__remaining) < __m) { *__out = *__first; ++__out; --__m; } --__remaining; ++__first; } return __out; } template _RandomAccessIterator __random_sample(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __out, const _Distance __n) { _Distance __m = 0; _Distance __t = __n; for ( ; __first != __last && __m < __n; ++__m, ++__first) __out[__m] = *__first; while (__first != __last) { ++__t; _Distance __M = std::rand() % (__t); if (__M < __n) __out[__M] = *__first; ++__first; } return __out + __m; } template _RandomAccessIterator __random_sample(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __out, _RandomNumberGenerator& __rand, const _Distance __n) { // concept requirements __glibcxx_function_requires(_UnaryFunctionConcept< _RandomNumberGenerator, _Distance, _Distance>) _Distance __m = 0; _Distance __t = __n; for ( ; __first != __last && __m < __n; ++__m, ++__first) __out[__m] = *__first; while (__first != __last) { ++__t; _Distance __M = __rand(__t); if (__M < __n) __out[__M] = *__first; ++__first; } return __out + __m; } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template inline _RandomAccessIterator random_sample(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __out_first, _RandomAccessIterator __out_last) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_valid_range(__out_first, __out_last); return __random_sample(__first, __last, __out_first, __out_last - __out_first); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template inline _RandomAccessIterator random_sample(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __out_first, _RandomAccessIterator __out_last, _RandomNumberGenerator& __rand) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_valid_range(__out_first, __out_last); return __random_sample(__first, __last, __out_first, __rand, __out_last - __out_first); } #if __cplusplus >= 201103L using std::is_heap; #else /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template inline bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__is_heap(__first, __last - __first); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template inline bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _StrictWeakOrdering __comp) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, typename iterator_traits<_RandomAccessIterator>::value_type, typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__is_heap(__first, __comp, __last - __first); } #endif #if __cplusplus >= 201103L using std::is_sorted; #else // is_sorted, a predicated testing whether a range is sorted in // nondescending order. This is an extension, not part of the C++ // standard. /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template bool is_sorted(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return true; _ForwardIterator __next = __first; for (++__next; __next != __last; __first = __next, ++__next) if (*__next < *__first) return false; return true; } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template bool is_sorted(_ForwardIterator __first, _ForwardIterator __last, _StrictWeakOrdering __comp) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return true; _ForwardIterator __next = __first; for (++__next; __next != __last; __first = __next, ++__next) if (__comp(*__next, *__first)) return false; return true; } #endif // C++11 /** * @brief Find the median of three values. * @param __a A value. * @param __b A value. * @param __c A value. * @return One of @p a, @p b or @p c. * * If @c {l,m,n} is some convolution of @p {a,b,c} such that @c l<=m<=n * then the value returned will be @c m. * This is an SGI extension. * @ingroup SGIextensions */ template const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) { // concept requirements __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) if (__a < __b) if (__b < __c) return __b; else if (__a < __c) return __c; else return __a; else if (__a < __c) return __a; else if (__b < __c) return __c; else return __b; } /** * @brief Find the median of three values using a predicate for comparison. * @param __a A value. * @param __b A value. * @param __c A value. * @param __comp A binary predicate. * @return One of @p a, @p b or @p c. * * If @c {l,m,n} is some convolution of @p {a,b,c} such that @p comp(l,m) * and @p comp(m,n) are both true then the value returned will be @c m. * This is an SGI extension. * @ingroup SGIextensions */ template const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) { // concept requirements __glibcxx_function_requires(_BinaryFunctionConcept<_Compare, bool, _Tp, _Tp>) if (__comp(__a, __b)) if (__comp(__b, __c)) return __b; else if (__comp(__a, __c)) return __c; else return __a; else if (__comp(__a, __c)) return __a; else if (__comp(__b, __c)) return __c; else return __b; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _EXT_ALGORITHM */ 8/ext/hash_set000064400000041453152526447530007260 0ustar00// Hashing set implementation -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * Copyright (c) 1996 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ /** @file backward/hash_set * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _BACKWARD_HASH_SET #define _BACKWARD_HASH_SET 1 #ifndef _GLIBCXX_PERMIT_BACKWARD_HASH #include "backward_warning.h" #endif #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::equal_to; using std::allocator; using std::pair; using std::_Identity; /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template, class _EqualKey = equal_to<_Value>, class _Alloc = allocator<_Value> > class hash_set { // concept requirements __glibcxx_class_requires(_Value, _SGIAssignableConcept) __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) private: typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, _Alloc> _Ht; _Ht _M_ht; public: typedef typename _Ht::key_type key_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Alloc::pointer pointer; typedef typename _Alloc::const_pointer const_pointer; typedef typename _Alloc::reference reference; typedef typename _Alloc::const_reference const_reference; typedef typename _Ht::const_iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } hash_set() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_set(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_set(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} template hash_set(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_set(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_set(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_unique(__f, __l); } template hash_set(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_unique(__f, __l); } size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); } template friend bool operator==(const hash_set<_Val, _HF, _EqK, _Al>&, const hash_set<_Val, _HF, _EqK, _Al>&); iterator begin() const { return _M_ht.begin(); } iterator end() const { return _M_ht.end(); } pair insert(const value_type& __obj) { pair __p = _M_ht.insert_unique(__obj); return pair(__p.first, __p.second); } template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f, __l); } pair insert_noresize(const value_type& __obj) { pair __p = _M_ht.insert_unique_noresize(__obj); return pair(__p.first, __p.second); } iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } size_type erase(const key_type& __key) {return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } void clear() { _M_ht.clear(); } void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template inline bool operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) { return __hs1._M_ht == __hs2._M_ht; } template inline bool operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) { return !(__hs1 == __hs2); } template inline void swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { __hs1.swap(__hs2); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template, class _EqualKey = equal_to<_Value>, class _Alloc = allocator<_Value> > class hash_multiset { // concept requirements __glibcxx_class_requires(_Value, _SGIAssignableConcept) __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept) __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept) private: typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, _Alloc> _Ht; _Ht _M_ht; public: typedef typename _Ht::key_type key_type; typedef typename _Ht::value_type value_type; typedef typename _Ht::hasher hasher; typedef typename _Ht::key_equal key_equal; typedef typename _Ht::size_type size_type; typedef typename _Ht::difference_type difference_type; typedef typename _Alloc::pointer pointer; typedef typename _Alloc::const_pointer const_pointer; typedef typename _Alloc::reference reference; typedef typename _Alloc::const_reference const_reference; typedef typename _Ht::const_iterator iterator; typedef typename _Ht::const_iterator const_iterator; typedef typename _Ht::allocator_type allocator_type; hasher hash_funct() const { return _M_ht.hash_funct(); } key_equal key_eq() const { return _M_ht.key_eq(); } allocator_type get_allocator() const { return _M_ht.get_allocator(); } hash_multiset() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} explicit hash_multiset(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} hash_multiset(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} template hash_multiset(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) { _M_ht.insert_equal(__f, __l); } template hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) { _M_ht.insert_equal(__f, __l); } size_type size() const { return _M_ht.size(); } size_type max_size() const { return _M_ht.max_size(); } bool empty() const { return _M_ht.empty(); } void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); } template friend bool operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&, const hash_multiset<_Val, _HF, _EqK, _Al>&); iterator begin() const { return _M_ht.begin(); } iterator end() const { return _M_ht.end(); } iterator insert(const value_type& __obj) { return _M_ht.insert_equal(__obj); } template void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } iterator insert_noresize(const value_type& __obj) { return _M_ht.insert_equal_noresize(__obj); } iterator find(const key_type& __key) const { return _M_ht.find(__key); } size_type count(const key_type& __key) const { return _M_ht.count(__key); } pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } size_type erase(const key_type& __key) { return _M_ht.erase(__key); } void erase(iterator __it) { _M_ht.erase(__it); } void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } void clear() { _M_ht.clear(); } void resize(size_type __hint) { _M_ht.resize(__hint); } size_type bucket_count() const { return _M_ht.bucket_count(); } size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } }; template inline bool operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { return __hs1._M_ht == __hs2._M_ht; } template inline bool operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { return !(__hs1 == __hs2); } template inline void swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) { __hs1.swap(__hs2); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Specialization of insert_iterator so that it will work for hash_set // and hash_multiset. template class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> > { protected: typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc> _Container; _Container* container; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; template class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> > { protected: typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc> _Container; _Container* container; typename _Container::iterator iter; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; insert_iterator(_Container& __x) : container(&__x) {} insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->insert(__value); return *this; } insert_iterator<_Container>& operator*() { return *this; } insert_iterator<_Container>& operator++() { return *this; } insert_iterator<_Container>& operator++(int) { return *this; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/ext/string_conversions.h000064400000007015152526447530011642 0ustar00// String Conversions -*- C++ -*- // Copyright (C) 2008-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ext/string_conversions.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _STRING_CONVERSIONS_H #define _STRING_CONVERSIONS_H 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include #include #include #include #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Helper for all the sto* functions. template _Ret __stoa(_TRet (*__convf) (const _CharT*, _CharT**, _Base...), const char* __name, const _CharT* __str, std::size_t* __idx, _Base... __base) { _Ret __ret; _CharT* __endptr; struct _Save_errno { _Save_errno() : _M_errno(errno) { errno = 0; } ~_Save_errno() { if (errno == 0) errno = _M_errno; } int _M_errno; } const __save_errno; struct _Range_chk { static bool _S_chk(_TRet, std::false_type) { return false; } static bool _S_chk(_TRet __val, std::true_type) // only called when _Ret is int { return __val < _TRet(__numeric_traits::__min) || __val > _TRet(__numeric_traits::__max); } }; const _TRet __tmp = __convf(__str, &__endptr, __base...); if (__endptr == __str) std::__throw_invalid_argument(__name); else if (errno == ERANGE || _Range_chk::_S_chk(__tmp, std::is_same<_Ret, int>{})) std::__throw_out_of_range(__name); else __ret = __tmp; if (__idx) *__idx = __endptr - __str; return __ret; } // Helper for the to_string / to_wstring functions. template _String __to_xstring(int (*__convf) (_CharT*, std::size_t, const _CharT*, __builtin_va_list), std::size_t __n, const _CharT* __fmt, ...) { // XXX Eventually the result should be constructed in-place in // the __cxx11 string, likely with the help of internal hooks. _CharT* __s = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n)); __builtin_va_list __args; __builtin_va_start(__args, __fmt); const int __len = __convf(__s, __n, __fmt, __args); __builtin_va_end(__args); return _String(__s, __s + __len); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #endif // _STRING_CONVERSIONS_H 8/ext/codecvt_specializations.h000064400000037741152526447530012625 0ustar00// Locale support (codecvt) -*- C++ -*- // Copyright (C) 2000-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . // // ISO C++ 14882: 22.2.1.5 Template class codecvt // // Written by Benjamin Kosnik /** @file ext/codecvt_specializations.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_CODECVT_SPECIALIZATIONS_H #define _EXT_CODECVT_SPECIALIZATIONS_H 1 #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CXX11 /// Extension to use iconv for dealing with character encodings. // This includes conversions and comparisons between various character // sets. This object encapsulates data that may need to be shared between // char_traits, codecvt and ctype. class encoding_state { public: // Types: // NB: A conversion descriptor subsumes and enhances the // functionality of a simple state type such as mbstate_t. typedef iconv_t descriptor_type; protected: // Name of internal character set encoding. std::string _M_int_enc; // Name of external character set encoding. std::string _M_ext_enc; // Conversion descriptor between external encoding to internal encoding. descriptor_type _M_in_desc; // Conversion descriptor between internal encoding to external encoding. descriptor_type _M_out_desc; // The byte-order marker for the external encoding, if necessary. int _M_ext_bom; // The byte-order marker for the internal encoding, if necessary. int _M_int_bom; // Number of external bytes needed to construct one complete // character in the internal encoding. // NB: -1 indicates variable, or stateful, encodings. int _M_bytes; public: explicit encoding_state() : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0), _M_bytes(0) { } explicit encoding_state(const char* __int, const char* __ext, int __ibom = 0, int __ebom = 0, int __bytes = 1) : _M_int_enc(__int), _M_ext_enc(__ext), _M_in_desc(0), _M_out_desc(0), _M_ext_bom(__ebom), _M_int_bom(__ibom), _M_bytes(__bytes) { init(); } // 21.1.2 traits typedefs // p4 // typedef STATE_T state_type // requires: state_type shall meet the requirements of // CopyConstructible types (20.1.3) // NB: This does not preserve the actual state of the conversion // descriptor member, but it does duplicate the encoding // information. encoding_state(const encoding_state& __obj) : _M_in_desc(0), _M_out_desc(0) { construct(__obj); } // Need assignment operator as well. encoding_state& operator=(const encoding_state& __obj) { construct(__obj); return *this; } ~encoding_state() { destroy(); } bool good() const throw() { const descriptor_type __err = (iconv_t)(-1); bool __test = _M_in_desc && _M_in_desc != __err; __test &= _M_out_desc && _M_out_desc != __err; return __test; } int character_ratio() const { return _M_bytes; } const std::string internal_encoding() const { return _M_int_enc; } int internal_bom() const { return _M_int_bom; } const std::string external_encoding() const { return _M_ext_enc; } int external_bom() const { return _M_ext_bom; } const descriptor_type& in_descriptor() const { return _M_in_desc; } const descriptor_type& out_descriptor() const { return _M_out_desc; } protected: void init() { const descriptor_type __err = (iconv_t)(-1); const bool __have_encodings = _M_int_enc.size() && _M_ext_enc.size(); if (!_M_in_desc && __have_encodings) { _M_in_desc = iconv_open(_M_int_enc.c_str(), _M_ext_enc.c_str()); if (_M_in_desc == __err) std::__throw_runtime_error(__N("encoding_state::_M_init " "creating iconv input descriptor failed")); } if (!_M_out_desc && __have_encodings) { _M_out_desc = iconv_open(_M_ext_enc.c_str(), _M_int_enc.c_str()); if (_M_out_desc == __err) std::__throw_runtime_error(__N("encoding_state::_M_init " "creating iconv output descriptor failed")); } } void construct(const encoding_state& __obj) { destroy(); _M_int_enc = __obj._M_int_enc; _M_ext_enc = __obj._M_ext_enc; _M_ext_bom = __obj._M_ext_bom; _M_int_bom = __obj._M_int_bom; _M_bytes = __obj._M_bytes; init(); } void destroy() throw() { const descriptor_type __err = (iconv_t)(-1); if (_M_in_desc && _M_in_desc != __err) { iconv_close(_M_in_desc); _M_in_desc = 0; } if (_M_out_desc && _M_out_desc != __err) { iconv_close(_M_out_desc); _M_out_desc = 0; } } }; /// encoding_char_traits // Custom traits type with encoding_state for the state type, and the // associated fpos for the position type, all other // bits equivalent to the required char_traits instantiations. template struct encoding_char_traits : public std::char_traits<_CharT> { typedef encoding_state state_type; typedef typename std::fpos pos_type; }; _GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using __gnu_cxx::encoding_state; /// codecvt specialization. // This partial specialization takes advantage of iconv to provide // code conversions between a large number of character encodings. template class codecvt<_InternT, _ExternT, encoding_state> : public __codecvt_abstract_base<_InternT, _ExternT, encoding_state> { public: // Types: typedef codecvt_base::result result; typedef _InternT intern_type; typedef _ExternT extern_type; typedef __gnu_cxx::encoding_state state_type; typedef state_type::descriptor_type descriptor_type; // Data Members: static locale::id id; explicit codecvt(size_t __refs = 0) : __codecvt_abstract_base(__refs) { } explicit codecvt(state_type& __enc, size_t __refs = 0) : __codecvt_abstract_base(__refs) { } protected: virtual ~codecvt() { } virtual result do_out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; virtual result do_unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; virtual result do_in(state_type& __state, const extern_type* __from, const extern_type* __from_end, const extern_type*& __from_next, intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const; virtual int do_encoding() const throw(); virtual bool do_always_noconv() const throw(); virtual int do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; virtual int do_max_length() const throw(); }; template locale::id codecvt<_InternT, _ExternT, encoding_state>::id; // This adaptor works around the signature problems of the second // argument to iconv(): SUSv2 and others use 'const char**', but glibc 2.2 // uses 'char**', which matches the POSIX 1003.1-2001 standard. // Using this adaptor, g++ will do the work for us. template inline size_t __iconv_adaptor(size_t(*__func)(iconv_t, _Tp, size_t*, char**, size_t*), iconv_t __cd, char** __inbuf, size_t* __inbytes, char** __outbuf, size_t* __outbytes) { return __func(__cd, (_Tp)__inbuf, __inbytes, __outbuf, __outbytes); } template codecvt_base::result codecvt<_InternT, _ExternT, encoding_state>:: do_out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const { result __ret = codecvt_base::error; if (__state.good()) { const descriptor_type& __desc = __state.out_descriptor(); const size_t __fmultiple = sizeof(intern_type); size_t __fbytes = __fmultiple * (__from_end - __from); const size_t __tmultiple = sizeof(extern_type); size_t __tbytes = __tmultiple * (__to_end - __to); // Argument list for iconv specifies a byte sequence. Thus, // all to/from arrays must be brutally casted to char*. char* __cto = reinterpret_cast(__to); char* __cfrom; size_t __conv; // Some encodings need a byte order marker as the first item // in the byte stream, to designate endian-ness. The default // value for the byte order marker is NULL, so if this is // the case, it's not necessary and we can just go on our // merry way. int __int_bom = __state.internal_bom(); if (__int_bom) { size_t __size = __from_end - __from; intern_type* __cfixed = static_cast (__builtin_alloca(sizeof(intern_type) * (__size + 1))); __cfixed[0] = static_cast(__int_bom); char_traits::copy(__cfixed + 1, __from, __size); __cfrom = reinterpret_cast(__cfixed); __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__fbytes, &__cto, &__tbytes); } else { intern_type* __cfixed = const_cast(__from); __cfrom = reinterpret_cast(__cfixed); __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__fbytes, &__cto, &__tbytes); } if (__conv != size_t(-1)) { __from_next = reinterpret_cast(__cfrom); __to_next = reinterpret_cast(__cto); __ret = codecvt_base::ok; } else { if (__fbytes < __fmultiple * (__from_end - __from)) { __from_next = reinterpret_cast(__cfrom); __to_next = reinterpret_cast(__cto); __ret = codecvt_base::partial; } else __ret = codecvt_base::error; } } return __ret; } template codecvt_base::result codecvt<_InternT, _ExternT, encoding_state>:: do_unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const { result __ret = codecvt_base::error; if (__state.good()) { const descriptor_type& __desc = __state.in_descriptor(); const size_t __tmultiple = sizeof(intern_type); size_t __tlen = __tmultiple * (__to_end - __to); // Argument list for iconv specifies a byte sequence. Thus, // all to/from arrays must be brutally casted to char*. char* __cto = reinterpret_cast(__to); size_t __conv = __iconv_adaptor(iconv,__desc, 0, 0, &__cto, &__tlen); if (__conv != size_t(-1)) { __to_next = reinterpret_cast(__cto); if (__tlen == __tmultiple * (__to_end - __to)) __ret = codecvt_base::noconv; else if (__tlen == 0) __ret = codecvt_base::ok; else __ret = codecvt_base::partial; } else __ret = codecvt_base::error; } return __ret; } template codecvt_base::result codecvt<_InternT, _ExternT, encoding_state>:: do_in(state_type& __state, const extern_type* __from, const extern_type* __from_end, const extern_type*& __from_next, intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const { result __ret = codecvt_base::error; if (__state.good()) { const descriptor_type& __desc = __state.in_descriptor(); const size_t __fmultiple = sizeof(extern_type); size_t __flen = __fmultiple * (__from_end - __from); const size_t __tmultiple = sizeof(intern_type); size_t __tlen = __tmultiple * (__to_end - __to); // Argument list for iconv specifies a byte sequence. Thus, // all to/from arrays must be brutally casted to char*. char* __cto = reinterpret_cast(__to); char* __cfrom; size_t __conv; // Some encodings need a byte order marker as the first item // in the byte stream, to designate endian-ness. The default // value for the byte order marker is NULL, so if this is // the case, it's not necessary and we can just go on our // merry way. int __ext_bom = __state.external_bom(); if (__ext_bom) { size_t __size = __from_end - __from; extern_type* __cfixed = static_cast (__builtin_alloca(sizeof(extern_type) * (__size + 1))); __cfixed[0] = static_cast(__ext_bom); char_traits::copy(__cfixed + 1, __from, __size); __cfrom = reinterpret_cast(__cfixed); __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__flen, &__cto, &__tlen); } else { extern_type* __cfixed = const_cast(__from); __cfrom = reinterpret_cast(__cfixed); __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__flen, &__cto, &__tlen); } if (__conv != size_t(-1)) { __from_next = reinterpret_cast(__cfrom); __to_next = reinterpret_cast(__cto); __ret = codecvt_base::ok; } else { if (__flen < static_cast(__from_end - __from)) { __from_next = reinterpret_cast(__cfrom); __to_next = reinterpret_cast(__cto); __ret = codecvt_base::partial; } else __ret = codecvt_base::error; } } return __ret; } template int codecvt<_InternT, _ExternT, encoding_state>:: do_encoding() const throw() { int __ret = 0; if (sizeof(_ExternT) <= sizeof(_InternT)) __ret = sizeof(_InternT) / sizeof(_ExternT); return __ret; } template bool codecvt<_InternT, _ExternT, encoding_state>:: do_always_noconv() const throw() { return false; } template int codecvt<_InternT, _ExternT, encoding_state>:: do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const { return std::min(__max, static_cast(__end - __from)); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 74. Garbled text for codecvt::do_max_length template int codecvt<_InternT, _ExternT, encoding_state>:: do_max_length() const throw() { return 1; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/ext/enc_filebuf.h000064400000004307152526447530010146 0ustar00// filebuf with encoding state type -*- C++ -*- // Copyright (C) 2002-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ext/enc_filebuf.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_ENC_FILEBUF_H #define _EXT_ENC_FILEBUF_H 1 #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// class enc_filebuf. template class enc_filebuf : public std::basic_filebuf<_CharT, encoding_char_traits<_CharT> > { public: typedef encoding_char_traits<_CharT> traits_type; typedef typename traits_type::state_type state_type; typedef typename traits_type::pos_type pos_type; enc_filebuf(state_type& __state) : std::basic_filebuf<_CharT, encoding_char_traits<_CharT> >() { this->_M_state_beg = __state; } private: // concept requirements: // Set state type to something useful. // Something more than copyconstructible is needed here, so // require default and copy constructible + assignment operator. __glibcxx_class_requires(state_type, _SGIAssignableConcept) }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/ext/vstring_util.h000064400000013207152526447530010435 0ustar00// Versatile string utility -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ext/vstring_util.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/vstring.h} */ #ifndef _VSTRING_UTIL_H #define _VSTRING_UTIL_H 1 #pragma GCC system_header #include #include #include // For less #include #include #include #include #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct __vstring_utility { typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type; typedef _Traits traits_type; typedef typename _Traits::char_type value_type; typedef typename _CharT_alloc_type::size_type size_type; typedef typename _CharT_alloc_type::difference_type difference_type; typedef typename _CharT_alloc_type::pointer pointer; typedef typename _CharT_alloc_type::const_pointer const_pointer; // For __sso_string. typedef __gnu_cxx:: __normal_iterator > __sso_iterator; typedef __gnu_cxx:: __normal_iterator > __const_sso_iterator; // For __rc_string. typedef __gnu_cxx:: __normal_iterator > __rc_iterator; typedef __gnu_cxx:: __normal_iterator > __const_rc_iterator; // NB: When the allocator is empty, deriving from it saves space // (http://www.cantrip.org/emptyopt.html). template struct _Alloc_hider : public _Alloc1 { _Alloc_hider(_CharT* __ptr) : _Alloc1(), _M_p(__ptr) { } _Alloc_hider(const _Alloc1& __a, _CharT* __ptr) : _Alloc1(__a), _M_p(__ptr) { } _CharT* _M_p; // The actual data. }; // When __n = 1 way faster than the general multichar // traits_type::copy/move/assign. static void _S_copy(_CharT* __d, const _CharT* __s, size_type __n) { if (__n == 1) traits_type::assign(*__d, *__s); else traits_type::copy(__d, __s, __n); } static void _S_move(_CharT* __d, const _CharT* __s, size_type __n) { if (__n == 1) traits_type::assign(*__d, *__s); else traits_type::move(__d, __s, __n); } static void _S_assign(_CharT* __d, size_type __n, _CharT __c) { if (__n == 1) traits_type::assign(*__d, __c); else traits_type::assign(__d, __n, __c); } // _S_copy_chars is a separate template to permit specialization // to optimize for the common case of pointers as iterators. template static void _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) { for (; __k1 != __k2; ++__k1, ++__p) traits_type::assign(*__p, *__k1); // These types are off. } static void _S_copy_chars(_CharT* __p, __sso_iterator __k1, __sso_iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, __const_sso_iterator __k1, __const_sso_iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, __rc_iterator __k1, __rc_iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, __const_rc_iterator __k1, __const_rc_iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) { _S_copy(__p, __k1, __k2 - __k1); } static void _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) { _S_copy(__p, __k1, __k2 - __k1); } static int _S_compare(size_type __n1, size_type __n2) { const difference_type __d = difference_type(__n1 - __n2); if (__d > __numeric_traits_integer::__max) return __numeric_traits_integer::__max; else if (__d < __numeric_traits_integer::__min) return __numeric_traits_integer::__min; else return int(__d); } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _VSTRING_UTIL_H */ 8/ext/array_allocator.h000064400000012412152526447530011057 0ustar00// array allocator -*- C++ -*- // Copyright (C) 2004-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ext/array_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _ARRAY_ALLOCATOR_H #define _ARRAY_ALLOCATOR_H 1 #include #include #include #include #include #if __cplusplus >= 201103L #include #endif // Suppress deprecated warning for this file. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; /// Base class. template class array_allocator_base { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; pointer address(reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } void deallocate(pointer, size_type) { // Does nothing. } size_type max_size() const _GLIBCXX_USE_NOEXCEPT { return size_t(-1) / sizeof(_Tp); } #if __cplusplus >= 201103L template void construct(_Up* __p, _Args&&... __args) { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } template void destroy(_Up* __p) { __p->~_Up(); } #else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) value_type(__val); } void destroy(pointer __p) { __p->~_Tp(); } #endif } _GLIBCXX_DEPRECATED; /** * @brief An allocator that uses previously allocated memory. * This memory can be externally, globally, or otherwise allocated. * @ingroup allocators */ template > class array_allocator : public array_allocator_base<_Tp> { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; typedef _Array array_type; #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. std::allocator propagate_on_container_move_assignment typedef std::true_type propagate_on_container_move_assignment; typedef std::true_type is_always_equal; #endif private: array_type* _M_array; size_type _M_used; public: template struct rebind { typedef array_allocator<_Tp1, _Array1> other _GLIBCXX_DEPRECATED; } _GLIBCXX_DEPRECATED; array_allocator(array_type* __array = 0) _GLIBCXX_USE_NOEXCEPT : _M_array(__array), _M_used(size_type()) { } array_allocator(const array_allocator& __o) _GLIBCXX_USE_NOEXCEPT : _M_array(__o._M_array), _M_used(__o._M_used) { } template array_allocator(const array_allocator<_Tp1, _Array1>&) _GLIBCXX_USE_NOEXCEPT : _M_array(0), _M_used(size_type()) { } ~array_allocator() _GLIBCXX_USE_NOEXCEPT { } pointer allocate(size_type __n, const void* = 0) { if (_M_array == 0 || _M_used + __n > _M_array->size()) std::__throw_bad_alloc(); pointer __ret = _M_array->begin() + _M_used; _M_used += __n; return __ret; } } _GLIBCXX_DEPRECATED; template inline bool operator==(const array_allocator<_Tp, _Array>&, const array_allocator<_Tp, _Array>&) { return true; } template inline bool operator!=(const array_allocator<_Tp, _Array>&, const array_allocator<_Tp, _Array>&) { return false; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #pragma GCC diagnostic pop #endif 8/ext/pool_allocator.h000064400000021165152526447530010717 0ustar00// Allocators -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * Copyright (c) 1996-1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file ext/pool_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _POOL_ALLOCATOR_H #define _POOL_ALLOCATOR_H 1 #include #include #include #include #include #include #include #if __cplusplus >= 201103L #include #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; /** * @brief Base class for __pool_alloc. * * Uses various allocators to fulfill underlying requests (and makes as * few requests as possible when in default high-speed pool mode). * * Important implementation properties: * 0. If globally mandated, then allocate objects from new * 1. If the clients request an object of size > _S_max_bytes, the resulting * object will be obtained directly from new * 2. In all other cases, we allocate an object of size exactly * _S_round_up(requested_size). Thus the client has enough size * information that we can return the object to the proper free list * without permanently losing part of the object. */ class __pool_alloc_base { protected: enum { _S_align = 8 }; enum { _S_max_bytes = 128 }; enum { _S_free_list_size = (size_t)_S_max_bytes / (size_t)_S_align }; union _Obj { union _Obj* _M_free_list_link; char _M_client_data[1]; // The client sees this. }; static _Obj* volatile _S_free_list[_S_free_list_size]; // Chunk allocation state. static char* _S_start_free; static char* _S_end_free; static size_t _S_heap_size; size_t _M_round_up(size_t __bytes) { return ((__bytes + (size_t)_S_align - 1) & ~((size_t)_S_align - 1)); } _GLIBCXX_CONST _Obj* volatile* _M_get_free_list(size_t __bytes) throw (); __mutex& _M_get_mutex() throw (); // Returns an object of size __n, and optionally adds to size __n // free list. void* _M_refill(size_t __n); // Allocates a chunk for nobjs of size size. nobjs may be reduced // if it is inconvenient to allocate the requested number. char* _M_allocate_chunk(size_t __n, int& __nobjs); }; /** * @brief Allocator using a memory pool with a single lock. * @ingroup allocators */ template class __pool_alloc : private __pool_alloc_base { private: static _Atomic_word _S_force_new; public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; template struct rebind { typedef __pool_alloc<_Tp1> other; }; #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. propagate_on_container_move_assignment typedef std::true_type propagate_on_container_move_assignment; #endif __pool_alloc() _GLIBCXX_USE_NOEXCEPT { } __pool_alloc(const __pool_alloc&) _GLIBCXX_USE_NOEXCEPT { } template __pool_alloc(const __pool_alloc<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { } ~__pool_alloc() _GLIBCXX_USE_NOEXCEPT { } pointer address(reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } size_type max_size() const _GLIBCXX_USE_NOEXCEPT { return size_t(-1) / sizeof(_Tp); } #if __cplusplus >= 201103L template void construct(_Up* __p, _Args&&... __args) { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } template void destroy(_Up* __p) { __p->~_Up(); } #else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) _Tp(__val); } void destroy(pointer __p) { __p->~_Tp(); } #endif pointer allocate(size_type __n, const void* = 0); void deallocate(pointer __p, size_type __n); }; template inline bool operator==(const __pool_alloc<_Tp>&, const __pool_alloc<_Tp>&) { return true; } template inline bool operator!=(const __pool_alloc<_Tp>&, const __pool_alloc<_Tp>&) { return false; } template _Atomic_word __pool_alloc<_Tp>::_S_force_new; template _Tp* __pool_alloc<_Tp>::allocate(size_type __n, const void*) { pointer __ret = 0; if (__builtin_expect(__n != 0, true)) { if (__n > this->max_size()) std::__throw_bad_alloc(); const size_t __bytes = __n * sizeof(_Tp); #if __cpp_aligned_new if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { std::align_val_t __al = std::align_val_t(alignof(_Tp)); return static_cast<_Tp*>(::operator new(__bytes, __al)); } #endif // If there is a race through here, assume answer from getenv // will resolve in same direction. Inspired by techniques // to efficiently support threading found in basic_string.h. if (_S_force_new == 0) { if (std::getenv("GLIBCXX_FORCE_NEW")) __atomic_add_dispatch(&_S_force_new, 1); else __atomic_add_dispatch(&_S_force_new, -1); } if (__bytes > size_t(_S_max_bytes) || _S_force_new > 0) __ret = static_cast<_Tp*>(::operator new(__bytes)); else { _Obj* volatile* __free_list = _M_get_free_list(__bytes); __scoped_lock sentry(_M_get_mutex()); _Obj* __restrict__ __result = *__free_list; if (__builtin_expect(__result == 0, 0)) __ret = static_cast<_Tp*>(_M_refill(_M_round_up(__bytes))); else { *__free_list = __result->_M_free_list_link; __ret = reinterpret_cast<_Tp*>(__result); } if (__ret == 0) std::__throw_bad_alloc(); } } return __ret; } template void __pool_alloc<_Tp>::deallocate(pointer __p, size_type __n) { if (__builtin_expect(__n != 0 && __p != 0, true)) { #if __cpp_aligned_new if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { ::operator delete(__p, std::align_val_t(alignof(_Tp))); return; } #endif const size_t __bytes = __n * sizeof(_Tp); if (__bytes > static_cast(_S_max_bytes) || _S_force_new > 0) ::operator delete(__p); else { _Obj* volatile* __free_list = _M_get_free_list(__bytes); _Obj* __q = reinterpret_cast<_Obj*>(__p); __scoped_lock sentry(_M_get_mutex()); __q ->_M_free_list_link = *__free_list; *__free_list = __q; } } } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/ext/stdio_sync_filebuf.h000064400000021116152526447530011554 0ustar00// Iostreams wrapper for stdio FILE* -*- C++ -*- // Copyright (C) 2003-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ext/stdio_sync_filebuf.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _STDIO_SYNC_FILEBUF_H #define _STDIO_SYNC_FILEBUF_H 1 #pragma GCC system_header #include #include #include #include // For __c_file #include // For __exchange #ifdef _GLIBCXX_USE_WCHAR_T #include #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Provides a layer of compatibility for C. * @ingroup io * * This GNU extension provides extensions for working with standard * C FILE*'s. It must be instantiated by the user with the type of * character used in the file stream, e.g., stdio_filebuf. */ template > class stdio_sync_filebuf : public std::basic_streambuf<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; private: typedef std::basic_streambuf<_CharT, _Traits> __streambuf_type; // Underlying stdio FILE std::__c_file* _M_file; // Last character gotten. This is used when pbackfail is // called from basic_streambuf::sungetc() int_type _M_unget_buf; public: explicit stdio_sync_filebuf(std::__c_file* __f) : _M_file(__f), _M_unget_buf(traits_type::eof()) { } #if __cplusplus >= 201103L stdio_sync_filebuf(stdio_sync_filebuf&& __fb) noexcept : __streambuf_type(std::move(__fb)), _M_file(__fb._M_file), _M_unget_buf(__fb._M_unget_buf) { __fb._M_file = nullptr; __fb._M_unget_buf = traits_type::eof(); } stdio_sync_filebuf& operator=(stdio_sync_filebuf&& __fb) noexcept { __streambuf_type::operator=(__fb); _M_file = std::__exchange(__fb._M_file, nullptr); _M_unget_buf = std::__exchange(__fb._M_unget_buf, traits_type::eof()); return *this; } void swap(stdio_sync_filebuf& __fb) { __streambuf_type::swap(__fb); std::swap(_M_file, __fb._M_file); std::swap(_M_unget_buf, __fb._M_unget_buf); } #endif /** * @return The underlying FILE*. * * This function can be used to access the underlying C file pointer. * Note that there is no way for the library to track what you do * with the file, so be careful. */ std::__c_file* file() { return this->_M_file; } protected: int_type syncgetc(); int_type syncungetc(int_type __c); int_type syncputc(int_type __c); virtual int_type underflow() { int_type __c = this->syncgetc(); return this->syncungetc(__c); } virtual int_type uflow() { // Store the gotten character in case we need to unget it. _M_unget_buf = this->syncgetc(); return _M_unget_buf; } virtual int_type pbackfail(int_type __c = traits_type::eof()) { int_type __ret; const int_type __eof = traits_type::eof(); // Check if the unget or putback was requested if (traits_type::eq_int_type(__c, __eof)) // unget { if (!traits_type::eq_int_type(_M_unget_buf, __eof)) __ret = this->syncungetc(_M_unget_buf); else // buffer invalid, fail. __ret = __eof; } else // putback __ret = this->syncungetc(__c); // The buffered character is no longer valid, discard it. _M_unget_buf = __eof; return __ret; } virtual std::streamsize xsgetn(char_type* __s, std::streamsize __n); virtual int_type overflow(int_type __c = traits_type::eof()) { int_type __ret; if (traits_type::eq_int_type(__c, traits_type::eof())) { if (std::fflush(_M_file)) __ret = traits_type::eof(); else __ret = traits_type::not_eof(__c); } else __ret = this->syncputc(__c); return __ret; } virtual std::streamsize xsputn(const char_type* __s, std::streamsize __n); virtual int sync() { return std::fflush(_M_file); } virtual std::streampos seekoff(std::streamoff __off, std::ios_base::seekdir __dir, std::ios_base::openmode = std::ios_base::in | std::ios_base::out) { std::streampos __ret(std::streamoff(-1)); int __whence; if (__dir == std::ios_base::beg) __whence = SEEK_SET; else if (__dir == std::ios_base::cur) __whence = SEEK_CUR; else __whence = SEEK_END; #ifdef _GLIBCXX_USE_LFS if (!fseeko64(_M_file, __off, __whence)) __ret = std::streampos(ftello64(_M_file)); #else if (!fseek(_M_file, __off, __whence)) __ret = std::streampos(std::ftell(_M_file)); #endif return __ret; } virtual std::streampos seekpos(std::streampos __pos, std::ios_base::openmode __mode = std::ios_base::in | std::ios_base::out) { return seekoff(std::streamoff(__pos), std::ios_base::beg, __mode); } }; template<> inline stdio_sync_filebuf::int_type stdio_sync_filebuf::syncgetc() { return std::getc(_M_file); } template<> inline stdio_sync_filebuf::int_type stdio_sync_filebuf::syncungetc(int_type __c) { return std::ungetc(__c, _M_file); } template<> inline stdio_sync_filebuf::int_type stdio_sync_filebuf::syncputc(int_type __c) { return std::putc(__c, _M_file); } template<> inline std::streamsize stdio_sync_filebuf::xsgetn(char* __s, std::streamsize __n) { std::streamsize __ret = std::fread(__s, 1, __n, _M_file); if (__ret > 0) _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]); else _M_unget_buf = traits_type::eof(); return __ret; } template<> inline std::streamsize stdio_sync_filebuf::xsputn(const char* __s, std::streamsize __n) { return std::fwrite(__s, 1, __n, _M_file); } #ifdef _GLIBCXX_USE_WCHAR_T template<> inline stdio_sync_filebuf::int_type stdio_sync_filebuf::syncgetc() { return std::getwc(_M_file); } template<> inline stdio_sync_filebuf::int_type stdio_sync_filebuf::syncungetc(int_type __c) { return std::ungetwc(__c, _M_file); } template<> inline stdio_sync_filebuf::int_type stdio_sync_filebuf::syncputc(int_type __c) { return std::putwc(__c, _M_file); } template<> inline std::streamsize stdio_sync_filebuf::xsgetn(wchar_t* __s, std::streamsize __n) { std::streamsize __ret = 0; const int_type __eof = traits_type::eof(); while (__n--) { int_type __c = this->syncgetc(); if (traits_type::eq_int_type(__c, __eof)) break; __s[__ret] = traits_type::to_char_type(__c); ++__ret; } if (__ret > 0) _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]); else _M_unget_buf = traits_type::eof(); return __ret; } template<> inline std::streamsize stdio_sync_filebuf::xsputn(const wchar_t* __s, std::streamsize __n) { std::streamsize __ret = 0; const int_type __eof = traits_type::eof(); while (__n--) { if (traits_type::eq_int_type(this->syncputc(*__s++), __eof)) break; ++__ret; } return __ret; } #endif #if _GLIBCXX_EXTERN_TEMPLATE extern template class stdio_sync_filebuf; #ifdef _GLIBCXX_USE_WCHAR_T extern template class stdio_sync_filebuf; #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/ext/random.tcc000064400000165527152526447530007523 0ustar00// Random number extensions -*- C++ -*- // Copyright (C) 2012-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ext/random.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/random} */ #ifndef _EXT_RANDOM_TCC #define _EXT_RANDOM_TCC 1 #pragma GCC system_header namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ template void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: seed(_UIntType __seed) { _M_state32[0] = static_cast(__seed); for (size_t __i = 1; __i < _M_nstate32; ++__i) _M_state32[__i] = (1812433253UL * (_M_state32[__i - 1] ^ (_M_state32[__i - 1] >> 30)) + __i); _M_pos = state_size; _M_period_certification(); } namespace { inline uint32_t _Func1(uint32_t __x) { return (__x ^ (__x >> 27)) * UINT32_C(1664525); } inline uint32_t _Func2(uint32_t __x) { return (__x ^ (__x >> 27)) * UINT32_C(1566083941); } } template template typename std::enable_if::value>::type simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: seed(_Sseq& __q) { size_t __lag; if (_M_nstate32 >= 623) __lag = 11; else if (_M_nstate32 >= 68) __lag = 7; else if (_M_nstate32 >= 39) __lag = 5; else __lag = 3; const size_t __mid = (_M_nstate32 - __lag) / 2; std::fill(_M_state32, _M_state32 + _M_nstate32, UINT32_C(0x8b8b8b8b)); uint32_t __arr[_M_nstate32]; __q.generate(__arr + 0, __arr + _M_nstate32); uint32_t __r = _Func1(_M_state32[0] ^ _M_state32[__mid] ^ _M_state32[_M_nstate32 - 1]); _M_state32[__mid] += __r; __r += _M_nstate32; _M_state32[__mid + __lag] += __r; _M_state32[0] = __r; for (size_t __i = 1, __j = 0; __j < _M_nstate32; ++__j) { __r = _Func1(_M_state32[__i] ^ _M_state32[(__i + __mid) % _M_nstate32] ^ _M_state32[(__i + _M_nstate32 - 1) % _M_nstate32]); _M_state32[(__i + __mid) % _M_nstate32] += __r; __r += __arr[__j] + __i; _M_state32[(__i + __mid + __lag) % _M_nstate32] += __r; _M_state32[__i] = __r; __i = (__i + 1) % _M_nstate32; } for (size_t __j = 0; __j < _M_nstate32; ++__j) { const size_t __i = (__j + 1) % _M_nstate32; __r = _Func2(_M_state32[__i] + _M_state32[(__i + __mid) % _M_nstate32] + _M_state32[(__i + _M_nstate32 - 1) % _M_nstate32]); _M_state32[(__i + __mid) % _M_nstate32] ^= __r; __r -= __i; _M_state32[(__i + __mid + __lag) % _M_nstate32] ^= __r; _M_state32[__i] = __r; } _M_pos = state_size; _M_period_certification(); } template void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: _M_period_certification(void) { static const uint32_t __parity[4] = { __parity1, __parity2, __parity3, __parity4 }; uint32_t __inner = 0; for (size_t __i = 0; __i < 4; ++__i) if (__parity[__i] != 0) __inner ^= _M_state32[__i] & __parity[__i]; if (__builtin_parity(__inner) & 1) return; for (size_t __i = 0; __i < 4; ++__i) if (__parity[__i] != 0) { _M_state32[__i] ^= 1 << (__builtin_ffs(__parity[__i]) - 1); return; } __builtin_unreachable(); } template void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: discard(unsigned long long __z) { while (__z > state_size - _M_pos) { __z -= state_size - _M_pos; _M_gen_rand(); } _M_pos += __z; } #ifndef _GLIBCXX_OPT_HAVE_RANDOM_SFMT_GEN_READ namespace { template inline void __rshift(uint32_t *__out, const uint32_t *__in) { uint64_t __th = ((static_cast(__in[3]) << 32) | static_cast(__in[2])); uint64_t __tl = ((static_cast(__in[1]) << 32) | static_cast(__in[0])); uint64_t __oh = __th >> (__shift * 8); uint64_t __ol = __tl >> (__shift * 8); __ol |= __th << (64 - __shift * 8); __out[1] = static_cast(__ol >> 32); __out[0] = static_cast(__ol); __out[3] = static_cast(__oh >> 32); __out[2] = static_cast(__oh); } template inline void __lshift(uint32_t *__out, const uint32_t *__in) { uint64_t __th = ((static_cast(__in[3]) << 32) | static_cast(__in[2])); uint64_t __tl = ((static_cast(__in[1]) << 32) | static_cast(__in[0])); uint64_t __oh = __th << (__shift * 8); uint64_t __ol = __tl << (__shift * 8); __oh |= __tl >> (64 - __shift * 8); __out[1] = static_cast(__ol >> 32); __out[0] = static_cast(__ol); __out[3] = static_cast(__oh >> 32); __out[2] = static_cast(__oh); } template inline void __recursion(uint32_t *__r, const uint32_t *__a, const uint32_t *__b, const uint32_t *__c, const uint32_t *__d) { uint32_t __x[4]; uint32_t __y[4]; __lshift<__sl2>(__x, __a); __rshift<__sr2>(__y, __c); __r[0] = (__a[0] ^ __x[0] ^ ((__b[0] >> __sr1) & __msk1) ^ __y[0] ^ (__d[0] << __sl1)); __r[1] = (__a[1] ^ __x[1] ^ ((__b[1] >> __sr1) & __msk2) ^ __y[1] ^ (__d[1] << __sl1)); __r[2] = (__a[2] ^ __x[2] ^ ((__b[2] >> __sr1) & __msk3) ^ __y[2] ^ (__d[2] << __sl1)); __r[3] = (__a[3] ^ __x[3] ^ ((__b[3] >> __sr1) & __msk4) ^ __y[3] ^ (__d[3] << __sl1)); } } template void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: _M_gen_rand(void) { const uint32_t *__r1 = &_M_state32[_M_nstate32 - 8]; const uint32_t *__r2 = &_M_state32[_M_nstate32 - 4]; static constexpr size_t __pos1_32 = __pos1 * 4; size_t __i; for (__i = 0; __i < _M_nstate32 - __pos1_32; __i += 4) { __recursion<__sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4> (&_M_state32[__i], &_M_state32[__i], &_M_state32[__i + __pos1_32], __r1, __r2); __r1 = __r2; __r2 = &_M_state32[__i]; } for (; __i < _M_nstate32; __i += 4) { __recursion<__sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4> (&_M_state32[__i], &_M_state32[__i], &_M_state32[__i + __pos1_32 - _M_nstate32], __r1, __r2); __r1 = __r2; __r2 = &_M_state32[__i]; } _M_pos = 0; } #endif #ifndef _GLIBCXX_OPT_HAVE_RANDOM_SFMT_OPERATOREQUAL template bool operator==(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs, const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs) { typedef __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4> __engine; return (std::equal(__lhs._M_stateT, __lhs._M_stateT + __engine::state_size, __rhs._M_stateT) && __lhs._M_pos == __rhs._M_pos); } #endif template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); __os.fill(__space); for (size_t __i = 0; __i < __x._M_nstate32; ++__i) __os << __x._M_state32[__i] << __space; __os << __x._M_pos; __os.flags(__flags); __os.fill(__fill); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); for (size_t __i = 0; __i < __x._M_nstate32; ++__i) __is >> __x._M_state32[__i]; __is >> __x._M_pos; __is.flags(__flags); return __is; } #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /** * Iteration method due to M.D. Jhnk. * * M.D. Jhnk, Erzeugung von betaverteilten und gammaverteilten * Zufallszahlen, Metrika, Volume 8, 1964 */ template template typename beta_distribution<_RealType>::result_type beta_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __x, __y; do { __x = std::exp(std::log(__aurng()) / __param.alpha()); __y = std::exp(std::log(__aurng()) / __param.beta()); } while (__x + __y > result_type(1)); return __x / (__x + __y); } template template void beta_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); while (__f != __t) { result_type __x, __y; do { __x = std::exp(std::log(__aurng()) / __param.alpha()); __y = std::exp(std::log(__aurng()) / __param.beta()); } while (__x + __y > result_type(1)); *__f++ = __x / (__x + __y); } } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::beta_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.alpha() << __space << __x.beta(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::beta_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __alpha_val, __beta_val; __is >> __alpha_val >> __beta_val; __x.param(typename __gnu_cxx::beta_distribution<_RealType>:: param_type(__alpha_val, __beta_val)); __is.flags(__flags); return __is; } template template void normal_mv_distribution<_Dimen, _RealType>::param_type:: _M_init_full(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend) { __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) std::fill(std::copy(__meanbegin, __meanend, _M_mean.begin()), _M_mean.end(), _RealType(0)); // Perform the Cholesky decomposition auto __w = _M_t.begin(); for (size_t __j = 0; __j < _Dimen; ++__j) { _RealType __sum = _RealType(0); auto __slitbegin = __w; auto __cit = _M_t.begin(); for (size_t __i = 0; __i < __j; ++__i) { auto __slit = __slitbegin; _RealType __s = *__varcovbegin++; for (size_t __k = 0; __k < __i; ++__k) __s -= *__slit++ * *__cit++; *__w++ = __s /= *__cit++; __sum += __s * __s; } __sum = *__varcovbegin - __sum; if (__builtin_expect(__sum <= _RealType(0), 0)) std::__throw_runtime_error(__N("normal_mv_distribution::" "param_type::_M_init_full")); *__w++ = std::sqrt(__sum); std::advance(__varcovbegin, _Dimen - __j); } } template template void normal_mv_distribution<_Dimen, _RealType>::param_type:: _M_init_lower(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend) { __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) std::fill(std::copy(__meanbegin, __meanend, _M_mean.begin()), _M_mean.end(), _RealType(0)); // Perform the Cholesky decomposition auto __w = _M_t.begin(); for (size_t __j = 0; __j < _Dimen; ++__j) { _RealType __sum = _RealType(0); auto __slitbegin = __w; auto __cit = _M_t.begin(); for (size_t __i = 0; __i < __j; ++__i) { auto __slit = __slitbegin; _RealType __s = *__varcovbegin++; for (size_t __k = 0; __k < __i; ++__k) __s -= *__slit++ * *__cit++; *__w++ = __s /= *__cit++; __sum += __s * __s; } __sum = *__varcovbegin++ - __sum; if (__builtin_expect(__sum <= _RealType(0), 0)) std::__throw_runtime_error(__N("normal_mv_distribution::" "param_type::_M_init_full")); *__w++ = std::sqrt(__sum); } } template template void normal_mv_distribution<_Dimen, _RealType>::param_type:: _M_init_diagonal(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varbegin, _InputIterator2 __varend) { __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) std::fill(std::copy(__meanbegin, __meanend, _M_mean.begin()), _M_mean.end(), _RealType(0)); auto __w = _M_t.begin(); size_t __step = 0; while (__varbegin != __varend) { std::fill_n(__w, __step, _RealType(0)); __w += __step++; if (__builtin_expect(*__varbegin < _RealType(0), 0)) std::__throw_runtime_error(__N("normal_mv_distribution::" "param_type::_M_init_diagonal")); *__w++ = std::sqrt(*__varbegin++); } } template template typename normal_mv_distribution<_Dimen, _RealType>::result_type normal_mv_distribution<_Dimen, _RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { result_type __ret; _M_nd.__generate(__ret.begin(), __ret.end(), __urng); auto __t_it = __param._M_t.crbegin(); for (size_t __i = _Dimen; __i > 0; --__i) { _RealType __sum = _RealType(0); for (size_t __j = __i; __j > 0; --__j) __sum += __ret[__j - 1] * *__t_it++; __ret[__i - 1] = __sum; } return __ret; } template template void normal_mv_distribution<_Dimen, _RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template bool operator==(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d1, const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d2) { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); auto __mean = __x._M_param.mean(); for (auto __it : __mean) __os << __it << __space; auto __t = __x._M_param.varcov(); for (auto __it : __t) __os << __it << __space; __os << __x._M_nd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); std::array<_RealType, _Dimen> __mean; for (auto& __it : __mean) __is >> __it; std::array<_RealType, _Dimen * (_Dimen + 1) / 2> __varcov; for (auto& __it : __varcov) __is >> __it; __is >> __x._M_nd; __x.param(typename normal_mv_distribution<_Dimen, _RealType>:: param_type(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end())); __is.flags(__flags); return __is; } template template void rice_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) { typename std::normal_distribution::param_type __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma()); result_type __x = this->_M_ndx(__px, __urng); result_type __y = this->_M_ndy(__py, __urng); #if _GLIBCXX_USE_C99_MATH_TR1 *__f++ = std::hypot(__x, __y); #else *__f++ = std::sqrt(__x * __x + __y * __y); #endif } } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const rice_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.nu() << __space << __x.sigma(); __os << __space << __x._M_ndx; __os << __space << __x._M_ndy; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, rice_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __nu_val, __sigma_val; __is >> __nu_val >> __sigma_val; __is >> __x._M_ndx; __is >> __x._M_ndy; __x.param(typename rice_distribution<_RealType>:: param_type(__nu_val, __sigma_val)); __is.flags(__flags); return __is; } template template void nakagami_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) typename std::gamma_distribution::param_type __pg(__p.mu(), __p.omega() / __p.mu()); while (__f != __t) *__f++ = std::sqrt(this->_M_gd(__pg, __urng)); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const nakagami_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.mu() << __space << __x.omega(); __os << __space << __x._M_gd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, nakagami_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __mu_val, __omega_val; __is >> __mu_val >> __omega_val; __is >> __x._M_gd; __x.param(typename nakagami_distribution<_RealType>:: param_type(__mu_val, __omega_val)); __is.flags(__flags); return __is; } template template void pareto_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) result_type __mu_val = __p.mu(); result_type __malphinv = -result_type(1) / __p.alpha(); while (__f != __t) *__f++ = __mu_val * std::pow(this->_M_ud(__urng), __malphinv); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const pareto_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.alpha() << __space << __x.mu(); __os << __space << __x._M_ud; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, pareto_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __alpha_val, __mu_val; __is >> __alpha_val >> __mu_val; __is >> __x._M_ud; __x.param(typename pareto_distribution<_RealType>:: param_type(__alpha_val, __mu_val)); __is.flags(__flags); return __is; } template template typename k_distribution<_RealType>::result_type k_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng) { result_type __x = this->_M_gd1(__urng); result_type __y = this->_M_gd2(__urng); return std::sqrt(__x * __y); } template template typename k_distribution<_RealType>::result_type k_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typename std::gamma_distribution::param_type __p1(__p.lambda(), result_type(1) / __p.lambda()), __p2(__p.nu(), __p.mu() / __p.nu()); result_type __x = this->_M_gd1(__p1, __urng); result_type __y = this->_M_gd2(__p2, __urng); return std::sqrt(__x * __y); } template template void k_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) typename std::gamma_distribution::param_type __p1(__p.lambda(), result_type(1) / __p.lambda()), __p2(__p.nu(), __p.mu() / __p.nu()); while (__f != __t) { result_type __x = this->_M_gd1(__p1, __urng); result_type __y = this->_M_gd2(__p2, __urng); *__f++ = std::sqrt(__x * __y); } } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const k_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.lambda() << __space << __x.mu() << __space << __x.nu(); __os << __space << __x._M_gd1; __os << __space << __x._M_gd2; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, k_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __lambda_val, __mu_val, __nu_val; __is >> __lambda_val >> __mu_val >> __nu_val; __is >> __x._M_gd1; __is >> __x._M_gd2; __x.param(typename k_distribution<_RealType>:: param_type(__lambda_val, __mu_val, __nu_val)); __is.flags(__flags); return __is; } template template void arcsine_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) result_type __dif = __p.b() - __p.a(); result_type __sum = __p.a() + __p.b(); while (__f != __t) { result_type __x = std::sin(this->_M_ud(__urng)); *__f++ = (__x * __dif + __sum) / result_type(2); } } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const arcsine_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.a() << __space << __x.b(); __os << __space << __x._M_ud; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, arcsine_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __a, __b; __is >> __a >> __b; __is >> __x._M_ud; __x.param(typename arcsine_distribution<_RealType>:: param_type(__a, __b)); __is.flags(__flags); return __is; } template template typename hoyt_distribution<_RealType>::result_type hoyt_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng) { result_type __x = this->_M_ad(__urng); result_type __y = this->_M_ed(__urng); return (result_type(2) * this->q() / (result_type(1) + this->q() * this->q())) * std::sqrt(this->omega() * __x * __y); } template template typename hoyt_distribution<_RealType>::result_type hoyt_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { result_type __q2 = __p.q() * __p.q(); result_type __num = result_type(0.5L) * (result_type(1) + __q2); typename __gnu_cxx::arcsine_distribution::param_type __pa(__num, __num / __q2); result_type __x = this->_M_ad(__pa, __urng); result_type __y = this->_M_ed(__urng); return (result_type(2) * __p.q() / (result_type(1) + __q2)) * std::sqrt(__p.omega() * __x * __y); } template template void hoyt_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) result_type __2q = result_type(2) * __p.q(); result_type __q2 = __p.q() * __p.q(); result_type __q2p1 = result_type(1) + __q2; result_type __num = result_type(0.5L) * __q2p1; result_type __omega = __p.omega(); typename __gnu_cxx::arcsine_distribution::param_type __pa(__num, __num / __q2); while (__f != __t) { result_type __x = this->_M_ad(__pa, __urng); result_type __y = this->_M_ed(__urng); *__f++ = (__2q / __q2p1) * std::sqrt(__omega * __x * __y); } } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const hoyt_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.q() << __space << __x.omega(); __os << __space << __x._M_ad; __os << __space << __x._M_ed; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, hoyt_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __q, __omega; __is >> __q >> __omega; __is >> __x._M_ad; __is >> __x._M_ed; __x.param(typename hoyt_distribution<_RealType>:: param_type(__q, __omega)); __is.flags(__flags); return __is; } template template void triangular_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::triangular_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.a() << __space << __x.b() << __space << __x.c(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::triangular_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __a, __b, __c; __is >> __a >> __b >> __c; __x.param(typename __gnu_cxx::triangular_distribution<_RealType>:: param_type(__a, __b, __c)); __is.flags(__flags); return __is; } template template typename von_mises_distribution<_RealType>::result_type von_mises_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { const result_type __pi = __gnu_cxx::__math_constants::__pi; std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __f; while (1) { result_type __rnd = std::cos(__pi * __aurng()); __f = (result_type(1) + __p._M_r * __rnd) / (__p._M_r + __rnd); result_type __c = __p._M_kappa * (__p._M_r - __f); result_type __rnd2 = __aurng(); if (__c * (result_type(2) - __c) > __rnd2) break; if (std::log(__c / __rnd2) >= __c - result_type(1)) break; } result_type __res = std::acos(__f); #if _GLIBCXX_USE_C99_MATH_TR1 __res = std::copysign(__res, __aurng() - result_type(0.5)); #else if (__aurng() < result_type(0.5)) __res = -__res; #endif __res += __p._M_mu; if (__res > __pi) __res -= result_type(2) * __pi; else if (__res < -__pi) __res += result_type(2) * __pi; return __res; } template template void von_mises_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::von_mises_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.mu() << __space << __x.kappa(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::von_mises_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __mu, __kappa; __is >> __mu >> __kappa; __x.param(typename __gnu_cxx::von_mises_distribution<_RealType>:: param_type(__mu, __kappa)); __is.flags(__flags); return __is; } template template typename hypergeometric_distribution<_UIntType>::result_type hypergeometric_distribution<_UIntType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); result_type __a = __param.successful_size(); result_type __b = __param.total_size(); result_type __k = 0; if (__param.total_draws() < __param.total_size() / 2) { for (result_type __i = 0; __i < __param.total_draws(); ++__i) { if (__b * __aurng() < __a) { ++__k; if (__k == __param.successful_size()) return __k; --__a; } --__b; } return __k; } else { for (result_type __i = 0; __i < __param.unsuccessful_size(); ++__i) { if (__b * __aurng() < __a) { ++__k; if (__k == __param.successful_size()) return __param.successful_size() - __k; --__a; } --__b; } return __param.successful_size() - __k; } } template template void hypergeometric_distribution<_UIntType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::hypergeometric_distribution<_UIntType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_UIntType>::max_digits10); __os << __x.total_size() << __space << __x.successful_size() << __space << __x.total_draws(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::hypergeometric_distribution<_UIntType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _UIntType __total_size, __successful_size, __total_draws; __is >> __total_size >> __successful_size >> __total_draws; __x.param(typename __gnu_cxx::hypergeometric_distribution<_UIntType>:: param_type(__total_size, __successful_size, __total_draws)); __is.flags(__flags); return __is; } template template typename logistic_distribution<_RealType>::result_type logistic_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __arg = result_type(1); while (__arg == result_type(1) || __arg == result_type(0)) __arg = __aurng(); return __p.a() + __p.b() * std::log(__arg / (result_type(1) - __arg)); } template template void logistic_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); while (__f != __t) { result_type __arg = result_type(1); while (__arg == result_type(1) || __arg == result_type(0)) __arg = __aurng(); *__f++ = __p.a() + __p.b() * std::log(__arg / (result_type(1) - __arg)); } } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const logistic_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.a() << __space << __x.b(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, logistic_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __a, __b; __is >> __a >> __b; __x.param(typename logistic_distribution<_RealType>:: param_type(__a, __b)); __is.flags(__flags); return __is; } namespace { // Helper class for the uniform_on_sphere_distribution generation // function. template class uniform_on_sphere_helper { typedef typename uniform_on_sphere_distribution<_Dimen, _RealType>:: result_type result_type; public: template result_type operator()(_NormalDistribution& __nd, _UniformRandomNumberGenerator& __urng) { result_type __ret; typename result_type::value_type __norm; do { auto __sum = _RealType(0); std::generate(__ret.begin(), __ret.end(), [&__nd, &__urng, &__sum](){ _RealType __t = __nd(__urng); __sum += __t * __t; return __t; }); __norm = std::sqrt(__sum); } while (__norm == _RealType(0) || ! __builtin_isfinite(__norm)); std::transform(__ret.begin(), __ret.end(), __ret.begin(), [__norm](_RealType __val){ return __val / __norm; }); return __ret; } }; template class uniform_on_sphere_helper<2, _RealType> { typedef typename uniform_on_sphere_distribution<2, _RealType>:: result_type result_type; public: template result_type operator()(_NormalDistribution&, _UniformRandomNumberGenerator& __urng) { result_type __ret; _RealType __sq; std::__detail::_Adaptor<_UniformRandomNumberGenerator, _RealType> __aurng(__urng); do { __ret[0] = _RealType(2) * __aurng() - _RealType(1); __ret[1] = _RealType(2) * __aurng() - _RealType(1); __sq = __ret[0] * __ret[0] + __ret[1] * __ret[1]; } while (__sq == _RealType(0) || __sq > _RealType(1)); #if _GLIBCXX_USE_C99_MATH_TR1 // Yes, we do not just use sqrt(__sq) because hypot() is more // accurate. auto __norm = std::hypot(__ret[0], __ret[1]); #else auto __norm = std::sqrt(__sq); #endif __ret[0] /= __norm; __ret[1] /= __norm; return __ret; } }; } template template typename uniform_on_sphere_distribution<_Dimen, _RealType>::result_type uniform_on_sphere_distribution<_Dimen, _RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { uniform_on_sphere_helper<_Dimen, _RealType> __helper; return __helper(_M_nd, __urng); } template template void uniform_on_sphere_distribution<_Dimen, _RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>& __x) { return __os << __x._M_nd; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>& __x) { return __is >> __x._M_nd; } namespace { // Helper class for the uniform_inside_sphere_distribution generation // function. template class uniform_inside_sphere_helper; template class uniform_inside_sphere_helper<_Dimen, false, _RealType> { using result_type = typename uniform_inside_sphere_distribution<_Dimen, _RealType>:: result_type; public: template result_type operator()(_UniformOnSphereDistribution& __uosd, _UniformRandomNumberGenerator& __urng, _RealType __radius) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, _RealType> __aurng(__urng); _RealType __pow = 1 / _RealType(_Dimen); _RealType __urt = __radius * std::pow(__aurng(), __pow); result_type __ret = __uosd(__aurng); std::transform(__ret.begin(), __ret.end(), __ret.begin(), [__urt](_RealType __val) { return __val * __urt; }); return __ret; } }; // Helper class for the uniform_inside_sphere_distribution generation // function specialized for small dimensions. template class uniform_inside_sphere_helper<_Dimen, true, _RealType> { using result_type = typename uniform_inside_sphere_distribution<_Dimen, _RealType>:: result_type; public: template result_type operator()(_UniformOnSphereDistribution&, _UniformRandomNumberGenerator& __urng, _RealType __radius) { result_type __ret; _RealType __sq; _RealType __radsq = __radius * __radius; std::__detail::_Adaptor<_UniformRandomNumberGenerator, _RealType> __aurng(__urng); do { __sq = _RealType(0); for (int i = 0; i < _Dimen; ++i) { __ret[i] = _RealType(2) * __aurng() - _RealType(1); __sq += __ret[i] * __ret[i]; } } while (__sq > _RealType(1)); for (int i = 0; i < _Dimen; ++i) __ret[i] *= __radius; return __ret; } }; } // namespace // // Experiments have shown that rejection is more efficient than transform // for dimensions less than 8. // template template typename uniform_inside_sphere_distribution<_Dimen, _RealType>::result_type uniform_inside_sphere_distribution<_Dimen, _RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { uniform_inside_sphere_helper<_Dimen, _Dimen < 8, _RealType> __helper; return __helper(_M_uosd, __urng, __p.radius()); } template template void uniform_inside_sphere_distribution<_Dimen, _RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, _RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.radius() << __space << __x._M_uosd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, _RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __radius_val; __is >> __radius_val >> __x._M_uosd; __x.param(typename uniform_inside_sphere_distribution<_Dimen, _RealType>:: param_type(__radius_val)); __is.flags(__flags); return __is; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx #endif // _EXT_RANDOM_TCC 8/ext/alloc_traits.h000064400000013106152526447530010362 0ustar00// Allocator traits -*- C++ -*- // Copyright (C) 2011-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ext/alloc_traits.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_ALLOC_TRAITS_H #define _EXT_ALLOC_TRAITS_H 1 #pragma GCC system_header #if __cplusplus >= 201103L # include # include #else # include // for __alloc_swap #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Uniform interface to C++98 and C++11 allocators. * @ingroup allocators */ template struct __alloc_traits #if __cplusplus >= 201103L : std::allocator_traits<_Alloc> #endif { typedef _Alloc allocator_type; #if __cplusplus >= 201103L typedef std::allocator_traits<_Alloc> _Base_type; typedef typename _Base_type::value_type value_type; typedef typename _Base_type::pointer pointer; typedef typename _Base_type::const_pointer const_pointer; typedef typename _Base_type::size_type size_type; typedef typename _Base_type::difference_type difference_type; // C++11 allocators do not define reference or const_reference typedef value_type& reference; typedef const value_type& const_reference; using _Base_type::allocate; using _Base_type::deallocate; using _Base_type::construct; using _Base_type::destroy; using _Base_type::max_size; private: template using __is_custom_pointer = std::__and_, std::__not_>>; public: // overload construct for non-standard pointer types template static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type construct(_Alloc& __a, _Ptr __p, _Args&&... __args) { _Base_type::construct(__a, std::__to_address(__p), std::forward<_Args>(__args)...); } // overload destroy for non-standard pointer types template static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type destroy(_Alloc& __a, _Ptr __p) { _Base_type::destroy(__a, std::__to_address(__p)); } static _Alloc _S_select_on_copy(const _Alloc& __a) { return _Base_type::select_on_container_copy_construction(__a); } static void _S_on_swap(_Alloc& __a, _Alloc& __b) { std::__alloc_on_swap(__a, __b); } static constexpr bool _S_propagate_on_copy_assign() { return _Base_type::propagate_on_container_copy_assignment::value; } static constexpr bool _S_propagate_on_move_assign() { return _Base_type::propagate_on_container_move_assignment::value; } static constexpr bool _S_propagate_on_swap() { return _Base_type::propagate_on_container_swap::value; } static constexpr bool _S_always_equal() { return _Base_type::is_always_equal::value; } static constexpr bool _S_nothrow_move() { return _S_propagate_on_move_assign() || _S_always_equal(); } template struct rebind { typedef typename _Base_type::template rebind_alloc<_Tp> other; }; #else typedef typename _Alloc::pointer pointer; typedef typename _Alloc::const_pointer const_pointer; typedef typename _Alloc::value_type value_type; typedef typename _Alloc::reference reference; typedef typename _Alloc::const_reference const_reference; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; static pointer allocate(_Alloc& __a, size_type __n) { return __a.allocate(__n); } static void deallocate(_Alloc& __a, pointer __p, size_type __n) { __a.deallocate(__p, __n); } template static void construct(_Alloc& __a, pointer __p, const _Tp& __arg) { __a.construct(__p, __arg); } static void destroy(_Alloc& __a, pointer __p) { __a.destroy(__p); } static size_type max_size(const _Alloc& __a) { return __a.max_size(); } static const _Alloc& _S_select_on_copy(const _Alloc& __a) { return __a; } static void _S_on_swap(_Alloc& __a, _Alloc& __b) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 431. Swapping containers with unequal allocators. std::__alloc_swap<_Alloc>::_S_do_it(__a, __b); } template struct rebind { typedef typename _Alloc::template rebind<_Tp>::other other; }; #endif }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx #endif 8/ext/functional000064400000033724152526447530007626 0ustar00// Functional extensions -*- C++ -*- // Copyright (C) 2002-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file ext/functional * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_FUNCTIONAL #define _EXT_FUNCTIONAL 1 #pragma GCC system_header #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::unary_function; using std::binary_function; using std::mem_fun1_t; using std::const_mem_fun1_t; using std::mem_fun1_ref_t; using std::const_mem_fun1_ref_t; /** The @c identity_element functions are not part of the C++ * standard; SGI provided them as an extension. Its argument is an * operation, and its return value is the identity element for that * operation. It is overloaded for addition and multiplication, * and you can overload it for your own nefarious operations. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template inline _Tp identity_element(std::plus<_Tp>) { return _Tp(0); } /// An \link SGIextensions SGI extension \endlink. template inline _Tp identity_element(std::multiplies<_Tp>) { return _Tp(1); } /** @} */ /** As an extension to the binders, SGI provided composition functors and * wrapper functions to aid in their creation. The @c unary_compose * functor is constructed from two functions/functors, @c f and @c g. * Calling @c operator() with a single argument @c x returns @c f(g(x)). * The function @c compose1 takes the two functions and constructs a * @c unary_compose variable for you. * * @c binary_compose is constructed from three functors, @c f, @c g1, * and @c g2. Its @c operator() returns @c f(g1(x),g2(x)). The function * compose2 takes f, g1, and g2, and constructs the @c binary_compose * instance for you. For example, if @c f returns an int, then * \code * int answer = (compose2(f,g1,g2))(x); * \endcode * is equivalent to * \code * int temp1 = g1(x); * int temp2 = g2(x); * int answer = f(temp1,temp2); * \endcode * But the first form is more compact, and can be passed around as a * functor to other algorithms. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template class unary_compose : public unary_function { protected: _Operation1 _M_fn1; _Operation2 _M_fn2; public: unary_compose(const _Operation1& __x, const _Operation2& __y) : _M_fn1(__x), _M_fn2(__y) {} typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const { return _M_fn1(_M_fn2(__x)); } }; /// An \link SGIextensions SGI extension \endlink. template inline unary_compose<_Operation1, _Operation2> compose1(const _Operation1& __fn1, const _Operation2& __fn2) { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); } /// An \link SGIextensions SGI extension \endlink. template class binary_compose : public unary_function { protected: _Operation1 _M_fn1; _Operation2 _M_fn2; _Operation3 _M_fn3; public: binary_compose(const _Operation1& __x, const _Operation2& __y, const _Operation3& __z) : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { } typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const { return _M_fn1(_M_fn2(__x), _M_fn3(__x)); } }; /// An \link SGIextensions SGI extension \endlink. template inline binary_compose<_Operation1, _Operation2, _Operation3> compose2(const _Operation1& __fn1, const _Operation2& __fn2, const _Operation3& __fn3) { return binary_compose<_Operation1, _Operation2, _Operation3> (__fn1, __fn2, __fn3); } /** @} */ /** As an extension, SGI provided a functor called @c identity. When a * functor is required but no operations are desired, this can be used as a * pass-through. Its @c operator() returns its argument unchanged. * * @addtogroup SGIextensions */ template struct identity : public std::_Identity<_Tp> {}; /** @c select1st and @c select2nd are extensions provided by SGI. Their * @c operator()s * take a @c std::pair as an argument, and return either the first member * or the second member, respectively. They can be used (especially with * the composition functors) to @a strip data from a sequence before * performing the remainder of an algorithm. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template struct select1st : public std::_Select1st<_Pair> {}; /// An \link SGIextensions SGI extension \endlink. template struct select2nd : public std::_Select2nd<_Pair> {}; /** @} */ // extension documented next template struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> { _Arg1 operator()(const _Arg1& __x, const _Arg2&) const { return __x; } }; template struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> { _Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; } }; /** The @c operator() of the @c project1st functor takes two arbitrary * arguments and returns the first one, while @c project2nd returns the * second one. They are extensions provided by SGI. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template struct project1st : public _Project1st<_Arg1, _Arg2> {}; /// An \link SGIextensions SGI extension \endlink. template struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; /** @} */ // extension documented next template struct _Constant_void_fun { typedef _Result result_type; result_type _M_val; _Constant_void_fun(const result_type& __v) : _M_val(__v) {} const result_type& operator()() const { return _M_val; } }; template struct _Constant_unary_fun { typedef _Argument argument_type; typedef _Result result_type; result_type _M_val; _Constant_unary_fun(const result_type& __v) : _M_val(__v) {} const result_type& operator()(const _Argument&) const { return _M_val; } }; template struct _Constant_binary_fun { typedef _Arg1 first_argument_type; typedef _Arg2 second_argument_type; typedef _Result result_type; _Result _M_val; _Constant_binary_fun(const _Result& __v) : _M_val(__v) {} const result_type& operator()(const _Arg1&, const _Arg2&) const { return _M_val; } }; /** These three functors are each constructed from a single arbitrary * variable/value. Later, their @c operator()s completely ignore any * arguments passed, and return the stored value. * - @c constant_void_fun's @c operator() takes no arguments * - @c constant_unary_fun's @c operator() takes one argument (ignored) * - @c constant_binary_fun's @c operator() takes two arguments (ignored) * * The helper creator functions @c constant0, @c constant1, and * @c constant2 each take a @a result argument and construct variables of * the appropriate functor type. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template struct constant_void_fun : public _Constant_void_fun<_Result> { constant_void_fun(const _Result& __v) : _Constant_void_fun<_Result>(__v) {} }; /// An \link SGIextensions SGI extension \endlink. template struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument> { constant_unary_fun(const _Result& __v) : _Constant_unary_fun<_Result, _Argument>(__v) {} }; /// An \link SGIextensions SGI extension \endlink. template struct constant_binary_fun : public _Constant_binary_fun<_Result, _Arg1, _Arg2> { constant_binary_fun(const _Result& __v) : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {} }; /// An \link SGIextensions SGI extension \endlink. template inline constant_void_fun<_Result> constant0(const _Result& __val) { return constant_void_fun<_Result>(__val); } /// An \link SGIextensions SGI extension \endlink. template inline constant_unary_fun<_Result, _Result> constant1(const _Result& __val) { return constant_unary_fun<_Result, _Result>(__val); } /// An \link SGIextensions SGI extension \endlink. template inline constant_binary_fun<_Result,_Result,_Result> constant2(const _Result& __val) { return constant_binary_fun<_Result, _Result, _Result>(__val); } /** @} */ /** The @c subtractive_rng class is documented on * SGI's site. * Note that this code assumes that @c int is 32 bits. * * @ingroup SGIextensions */ class subtractive_rng : public unary_function { private: unsigned int _M_table[55]; size_t _M_index1; size_t _M_index2; public: /// Returns a number less than the argument. unsigned int operator()(unsigned int __limit) { _M_index1 = (_M_index1 + 1) % 55; _M_index2 = (_M_index2 + 1) % 55; _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2]; return _M_table[_M_index1] % __limit; } void _M_initialize(unsigned int __seed) { unsigned int __k = 1; _M_table[54] = __seed; size_t __i; for (__i = 0; __i < 54; __i++) { size_t __ii = (21 * (__i + 1) % 55) - 1; _M_table[__ii] = __k; __k = __seed - __k; __seed = _M_table[__ii]; } for (int __loop = 0; __loop < 4; __loop++) { for (__i = 0; __i < 55; __i++) _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55]; } _M_index1 = 0; _M_index2 = 31; } /// Ctor allowing you to initialize the seed. subtractive_rng(unsigned int __seed) { _M_initialize(__seed); } /// Default ctor; initializes its state with some number you don't see. subtractive_rng() { _M_initialize(161803398u); } }; // Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref, // provided for backward compatibility, they are no longer part of // the C++ standard. template inline mem_fun1_t<_Ret, _Tp, _Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } template inline const_mem_fun1_t<_Ret, _Tp, _Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } template inline mem_fun1_ref_t<_Ret, _Tp, _Arg> mem_fun1_ref(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } template inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/ext/concurrence.h000064400000016673152526447530010224 0ustar00// Support for concurrent programing -*- C++ -*- // Copyright (C) 2003-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ext/concurrence.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _CONCURRENCE_H #define _CONCURRENCE_H 1 #pragma GCC system_header #include #include #include #include #include namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Available locking policies: // _S_single single-threaded code that doesn't need to be locked. // _S_mutex multi-threaded code that requires additional support // from gthr.h or abstraction layers in concurrence.h. // _S_atomic multi-threaded code using atomic operations. enum _Lock_policy { _S_single, _S_mutex, _S_atomic }; // Compile time constant that indicates prefered locking policy in // the current configuration. static const _Lock_policy __default_lock_policy = #ifdef __GTHREADS #if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) \ && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) _S_atomic; #else _S_mutex; #endif #else _S_single; #endif // NB: As this is used in libsupc++, need to only depend on // exception. No stdexception classes, no use of std::string. class __concurrence_lock_error : public std::exception { public: virtual char const* what() const throw() { return "__gnu_cxx::__concurrence_lock_error"; } }; class __concurrence_unlock_error : public std::exception { public: virtual char const* what() const throw() { return "__gnu_cxx::__concurrence_unlock_error"; } }; class __concurrence_broadcast_error : public std::exception { public: virtual char const* what() const throw() { return "__gnu_cxx::__concurrence_broadcast_error"; } }; class __concurrence_wait_error : public std::exception { public: virtual char const* what() const throw() { return "__gnu_cxx::__concurrence_wait_error"; } }; // Substitute for concurrence_error object in the case of -fno-exceptions. inline void __throw_concurrence_lock_error() { _GLIBCXX_THROW_OR_ABORT(__concurrence_lock_error()); } inline void __throw_concurrence_unlock_error() { _GLIBCXX_THROW_OR_ABORT(__concurrence_unlock_error()); } #ifdef __GTHREAD_HAS_COND inline void __throw_concurrence_broadcast_error() { _GLIBCXX_THROW_OR_ABORT(__concurrence_broadcast_error()); } inline void __throw_concurrence_wait_error() { _GLIBCXX_THROW_OR_ABORT(__concurrence_wait_error()); } #endif class __mutex { private: #if __GTHREADS && defined __GTHREAD_MUTEX_INIT __gthread_mutex_t _M_mutex = __GTHREAD_MUTEX_INIT; #else __gthread_mutex_t _M_mutex; #endif __mutex(const __mutex&); __mutex& operator=(const __mutex&); public: __mutex() { #if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT if (__gthread_active_p()) __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex); #endif } #if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT ~__mutex() { if (__gthread_active_p()) __gthread_mutex_destroy(&_M_mutex); } #endif void lock() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_mutex_lock(&_M_mutex) != 0) __throw_concurrence_lock_error(); } #endif } void unlock() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_mutex_unlock(&_M_mutex) != 0) __throw_concurrence_unlock_error(); } #endif } __gthread_mutex_t* gthread_mutex(void) { return &_M_mutex; } }; class __recursive_mutex { private: #if __GTHREADS && defined __GTHREAD_RECURSIVE_MUTEX_INIT __gthread_recursive_mutex_t _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT; #else __gthread_recursive_mutex_t _M_mutex; #endif __recursive_mutex(const __recursive_mutex&); __recursive_mutex& operator=(const __recursive_mutex&); public: __recursive_mutex() { #if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT if (__gthread_active_p()) __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex); #endif } #if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT ~__recursive_mutex() { if (__gthread_active_p()) __gthread_recursive_mutex_destroy(&_M_mutex); } #endif void lock() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_recursive_mutex_lock(&_M_mutex) != 0) __throw_concurrence_lock_error(); } #endif } void unlock() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0) __throw_concurrence_unlock_error(); } #endif } __gthread_recursive_mutex_t* gthread_recursive_mutex(void) { return &_M_mutex; } }; /// Scoped lock idiom. // Acquire the mutex here with a constructor call, then release with // the destructor call in accordance with RAII style. class __scoped_lock { public: typedef __mutex __mutex_type; private: __mutex_type& _M_device; __scoped_lock(const __scoped_lock&); __scoped_lock& operator=(const __scoped_lock&); public: explicit __scoped_lock(__mutex_type& __name) : _M_device(__name) { _M_device.lock(); } ~__scoped_lock() throw() { _M_device.unlock(); } }; #ifdef __GTHREAD_HAS_COND class __cond { private: #if __GTHREADS && defined __GTHREAD_COND_INIT __gthread_cond_t _M_cond = __GTHREAD_COND_INIT; #else __gthread_cond_t _M_cond; #endif __cond(const __cond&); __cond& operator=(const __cond&); public: __cond() { #if __GTHREADS && ! defined __GTHREAD_COND_INIT if (__gthread_active_p()) __GTHREAD_COND_INIT_FUNCTION(&_M_cond); #endif } #if __GTHREADS && ! defined __GTHREAD_COND_INIT ~__cond() { if (__gthread_active_p()) __gthread_cond_destroy(&_M_cond); } #endif void broadcast() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_cond_broadcast(&_M_cond) != 0) __throw_concurrence_broadcast_error(); } #endif } void wait(__mutex *mutex) { #if __GTHREADS { if (__gthread_cond_wait(&_M_cond, mutex->gthread_mutex()) != 0) __throw_concurrence_wait_error(); } #endif } void wait_recursive(__recursive_mutex *mutex) { #if __GTHREADS { if (__gthread_cond_wait_recursive(&_M_cond, mutex->gthread_recursive_mutex()) != 0) __throw_concurrence_wait_error(); } #endif } }; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif 8/ext/mt_allocator.h000064400000055723152526447530010375 0ustar00// MT-optimized allocator -*- C++ -*- // Copyright (C) 2003-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, 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 General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file ext/mt_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _MT_ALLOCATOR_H #define _MT_ALLOCATOR_H 1 #include #include #include #include #include #if __cplusplus >= 201103L #include #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; typedef void (*__destroy_handler)(void*); /// Base class for pool object. struct __pool_base { // Using short int as type for the binmap implies we are never // caching blocks larger than 32768 with this allocator. typedef unsigned short int _Binmap_type; // Variables used to configure the behavior of the allocator, // assigned and explained in detail below. struct _Tune { // Compile time constants for the default _Tune values. enum { _S_align = 8 }; enum { _S_max_bytes = 128 }; enum { _S_min_bin = 8 }; enum { _S_chunk_size = 4096 - 4 * sizeof(void*) }; enum { _S_max_threads = 4096 }; enum { _S_freelist_headroom = 10 }; // Alignment needed. // NB: In any case must be >= sizeof(_Block_record), that // is 4 on 32 bit machines and 8 on 64 bit machines. size_t _M_align; // Allocation requests (after round-up to power of 2) below // this value will be handled by the allocator. A raw new/ // call will be used for requests larger than this value. // NB: Must be much smaller than _M_chunk_size and in any // case <= 32768. size_t _M_max_bytes; // Size in bytes of the smallest bin. // NB: Must be a power of 2 and >= _M_align (and of course // much smaller than _M_max_bytes). size_t _M_min_bin; // In order to avoid fragmenting and minimize the number of // new() calls we always request new memory using this // value. Based on previous discussions on the libstdc++ // mailing list we have chosen the value below. // See http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html // NB: At least one order of magnitude > _M_max_bytes. size_t _M_chunk_size; // The maximum number of supported threads. For // single-threaded operation, use one. Maximum values will // vary depending on details of the underlying system. (For // instance, Linux 2.4.18 reports 4070 in // /proc/sys/kernel/threads-max, while Linux 2.6.6 reports // 65534) size_t _M_max_threads; // Each time a deallocation occurs in a threaded application // we make sure that there are no more than // _M_freelist_headroom % of used memory on the freelist. If // the number of additional records is more than // _M_freelist_headroom % of the freelist, we move these // records back to the global pool. size_t _M_freelist_headroom; // Set to true forces all allocations to use new(). bool _M_force_new; explicit _Tune() : _M_align(_S_align), _M_max_bytes(_S_max_bytes), _M_min_bin(_S_min_bin), _M_chunk_size(_S_chunk_size), _M_max_threads(_S_max_threads), _M_freelist_headroom(_S_freelist_headroom), _M_force_new(std::getenv("GLIBCXX_FORCE_NEW") ? true : false) { } explicit _Tune(size_t __align, size_t __maxb, size_t __minbin, size_t __chunk, size_t __maxthreads, size_t __headroom, bool __force) : _M_align(__align), _M_max_bytes(__maxb), _M_min_bin(__minbin), _M_chunk_size(__chunk), _M_max_threads(__maxthreads), _M_freelist_headroom(__headroom), _M_force_new(__force) { } }; struct _Block_address { void* _M_initial; _Block_address* _M_next; }; const _Tune& _M_get_options() const { return _M_options; } void _M_set_options(_Tune __t) { if (!_M_init) _M_options = __t; } bool _M_check_threshold(size_t __bytes) { return __bytes > _M_options._M_max_bytes || _M_options._M_force_new; } size_t _M_get_binmap(size_t __bytes) { return _M_binmap[__bytes]; } size_t _M_get_align() { return _M_options._M_align; } explicit __pool_base() : _M_options(_Tune()), _M_binmap(0), _M_init(false) { } explicit __pool_base(const _Tune& __options) : _M_options(__options), _M_binmap(0), _M_init(false) { } private: explicit __pool_base(const __pool_base&); __pool_base& operator=(const __pool_base&); protected: // Configuration options. _Tune _M_options; _Binmap_type* _M_binmap; // Configuration of the pool object via _M_options can happen // after construction but before initialization. After // initialization is complete, this variable is set to true. bool _M_init; }; /** * @brief Data describing the underlying memory pool, parameterized on * threading support. */ template class __pool; /// Specialization for single thread. template<> class __pool : public __pool_base { public: union _Block_record { // Points to the block_record of the next free block. _Block_record* _M_next; }; struct _Bin_record { // An "array" of pointers to the first free block. _Block_record** _M_first; // A list of the initial addresses of all allocated blocks. _Block_address* _M_address; }; void _M_initialize_once() { if (__builtin_expect(_M_init == false, false)) _M_initialize(); } void _M_destroy() throw(); char* _M_reserve_block(size_t __bytes, const size_t __thread_id); void _M_reclaim_block(char* __p, size_t __bytes) throw (); size_t _M_get_thread_id() { return 0; } const _Bin_record& _M_get_bin(size_t __which) { return _M_bin[__which]; } void _M_adjust_freelist(const _Bin_record&, _Block_record*, size_t) { } explicit __pool() : _M_bin(0), _M_bin_size(1) { } explicit __pool(const __pool_base::_Tune& __tune) : __pool_base(__tune), _M_bin(0), _M_bin_size(1) { } private: // An "array" of bin_records each of which represents a specific // power of 2 size. Memory to this "array" is allocated in // _M_initialize(). _Bin_record* _M_bin; // Actual value calculated in _M_initialize(). size_t _M_bin_size; void _M_initialize(); }; #ifdef __GTHREADS /// Specialization for thread enabled, via gthreads.h. template<> class __pool : public __pool_base { public: // Each requesting thread is assigned an id ranging from 1 to // _S_max_threads. Thread id 0 is used as a global memory pool. // In order to get constant performance on the thread assignment // routine, we keep a list of free ids. When a thread first // requests memory we remove the first record in this list and // stores the address in a __gthread_key. When initializing the // __gthread_key we specify a destructor. When this destructor // (i.e. the thread dies) is called, we return the thread id to // the front of this list. struct _Thread_record { // Points to next free thread id record. NULL if last record in list. _Thread_record* _M_next; // Thread id ranging from 1 to _S_max_threads. size_t _M_id; }; union _Block_record { // Points to the block_record of the next free block. _Block_record* _M_next; // The thread id of the thread which has requested this block. size_t _M_thread_id; }; struct _Bin_record { // An "array" of pointers to the first free block for each // thread id. Memory to this "array" is allocated in // _S_initialize() for _S_max_threads + global pool 0. _Block_record** _M_first; // A list of the initial addresses of all allocated blocks. _Block_address* _M_address; // An "array" of counters used to keep track of the amount of // blocks that are on the freelist/used for each thread id. // - Note that the second part of the allocated _M_used "array" // actually hosts (atomic) counters of reclaimed blocks: in // _M_reserve_block and in _M_reclaim_block those numbers are // subtracted from the first ones to obtain the actual size // of the "working set" of the given thread. // - Memory to these "arrays" is allocated in _S_initialize() // for _S_max_threads + global pool 0. size_t* _M_free; size_t* _M_used; // Each bin has its own mutex which is used to ensure data // integrity while changing "ownership" on a block. The mutex // is initialized in _S_initialize(). __gthread_mutex_t* _M_mutex; }; // XXX GLIBCXX_ABI Deprecated void _M_initialize(__destroy_handler); void _M_initialize_once() { if (__builtin_expect(_M_init == false, false)) _M_initialize(); } void _M_destroy() throw(); char* _M_reserve_block(size_t __bytes, const size_t __thread_id); void _M_reclaim_block(char* __p, size_t __bytes) throw (); const _Bin_record& _M_get_bin(size_t __which) { return _M_bin[__which]; } void _M_adjust_freelist(const _Bin_record& __bin, _Block_record* __block, size_t __thread_id) { if (__gthread_active_p()) { __block->_M_thread_id = __thread_id; --__bin._M_free[__thread_id]; ++__bin._M_used[__thread_id]; } } // XXX GLIBCXX_ABI Deprecated void _M_destroy_thread_key(void*) throw (); size_t _M_get_thread_id(); explicit __pool() : _M_bin(0), _M_bin_size(1), _M_thread_freelist(0) { } explicit __pool(const __pool_base::_Tune& __tune) : __pool_base(__tune), _M_bin(0), _M_bin_size(1), _M_thread_freelist(0) { } private: // An "array" of bin_records each of which represents a specific // power of 2 size. Memory to this "array" is allocated in // _M_initialize(). _Bin_record* _M_bin; // Actual value calculated in _M_initialize(). size_t _M_bin_size; _Thread_record* _M_thread_freelist; void* _M_thread_freelist_initial; void _M_initialize(); }; #endif template