From 5f3ed30ba480d2415b1319299cddf18d1e4d6298 Mon Sep 17 00:00:00 2001 From: Kamila Szewczyk Date: Sun, 12 Nov 2023 18:29:29 +0100 Subject: [PATCH] size context weighting --- langsmoke | 40 +- ref_6502 | 1496 ++++++-------- ref_apl | 403 ---- ref_c | 2815 +++------------------------ ref_cpp | 5557 +---------------------------------------------------- ref_java | 1377 +++---------- 6 files changed, 1222 insertions(+), 10466 deletions(-) diff --git a/langsmoke b/langsmoke index 7bf58c2..e879286 100755 --- a/langsmoke +++ b/langsmoke @@ -16,22 +16,34 @@ size=$(du -sm $1 | cut -f1) let "size++" src=$1 -bz3=$(bzip3 -vf $1 /dev/null 2>&1 | grep -oE "[0-9]+ bytes" | grep -oE "[0-9]+") +bz3=$(bzip3 -fc $1 | wc -c) +lz4=$(lz4 -1c $1 2>/dev/null | wc -c) + +max=$(du ref_* | sort -nr | head -n 1 | cut -f-1) +min=$(du ref_* | sort -n | head -n 1 | cut -f-1) +abs=$(python3 -c "print(abs($max-$min))") function do_stat { # 20MB cutoff. - l_stat=$(cat ref_$1 $src | head -c 20000000 | bzip3 -eb $size | wc -c) - l_ref=$2 - sim=$(python3 -c "print(100*(1-($l_stat - min($l_ref, $bz3)) / (max($l_ref, $bz3))))") - echo $sim + ss=$(du ref_$1 | cut -f-1) + + bz_stat=$(cat ref_$1 $src | head -c 20000000 | bzip3 -eb $size | wc -c) + bz_ref=$(cat ref_$1 | bzip3 -eb $size | wc -c) + bz_sim=$(python3 -c "print(100*($ss/$abs)*(1-($bz_stat - min($bz_ref, $bz3)) / (max($bz_ref, $bz3))))") + + lz_stat=$(cat ref_$1 $src | head -c 20000000 | lz4 -1c | wc -c) + lz_ref=$(cat ref_$1 | lz4 -1c | wc -c) + lz_sim=$(python3 -c "print(1000*($ss/$abs)*(1-($lz_stat - min($lz_ref, $lz4)) / (max($lz_ref, $lz4))))") + + echo "BZ3: $bz_sim, LZ4: $lz_sim" } -echo "C: $(do_stat c 38533)" -echo "C++: $(do_stat cpp 33606)" -echo "Java: $(do_stat java 61196)" -echo "6502: $(do_stat 6502 9039)" -echo "Z80: $(do_stat z80 20182)" -echo "APL: $(do_stat apl 29173)" -echo "x86: $(do_stat x86 25753)" -echo "x64: $(do_stat x64 17809)" -echo "Shell: $(do_stat sh 44144)" \ No newline at end of file +echo "C: $(do_stat c)" +echo "C++: $(do_stat cpp)" +echo "Java: $(do_stat java)" +echo "6502: $(do_stat 6502)" +echo "Z80: $(do_stat z80)" +echo "APL: $(do_stat apl)" +echo "x86: $(do_stat x86)" +echo "x64: $(do_stat x64)" +echo "Shell: $(do_stat sh)" \ No newline at end of file diff --git a/ref_6502 b/ref_6502 index 2e04eb9..4809a66 100644 --- a/ref_6502 +++ b/ref_6502 @@ -1,612 +1,408 @@ -; -; 6551 I/O Port Addresses -; -ACIADat = $7F70 -ACIASta = $7F71 -ACIACmd = $7F72 -ACIACtl = $7F73 -; -; page zero variables -; -BOARD = $50 -BK = $60 -PIECE = $B0 -SQUARE = $B1 -SP2 = $B2 -SP1 = $B3 -INCHEK = $B4 -STATE = $B5 -MOVEN = $B6 -REV = $B7 -OMOVE = $DC -WCAP0 = $DD -COUNT = $DE -BCAP2 = $DE -WCAP2 = $DF -BCAP1 = $E0 -WCAP1 = $E1 -BCAP0 = $E2 -MOB = $E3 -MAXC = $E4 -CC = $E5 -PCAP = $E6 -BMOB = $E3 -BMAXC = $E4 -BMCC = $E5 ; was BCC (TASS doesn't like it as a label) -BMAXP = $E6 -XMAXC = $E8 -WMOB = $EB -WMAXC = $EC -WCC = $ED -WMAXP = $EE -PMOB = $EF -PMAXC = $F0 -PCC = $F1 -PCP = $F2 -OLDKY = $F3 -BESTP = $FB -BESTV = $FA -BESTM = $F9 -DIS1 = $FB -DIS2 = $FA -DIS3 = $F9 -temp = $FC -; -; -; - *=$1000 ; load into RAM @ $1000-$15FF - - LDA #$00 ; REVERSE TOGGLE + *=$1000 + LDA #$00 STA REV - JSR Init_6551 -CHESS CLD ; INITIALIZE - LDX #$FF ; TWO STACKS + JSR Init_6551 +CHESS CLD + LDX #$FF TXS LDX #$C8 STX SP2 -; -; ROUTINES TO LIGHT LED -; DISPLAY AND GET KEY -; FROM KEYBOARD -; -OUT JSR pout ; DISPLAY AND - JSR KIN ; GET INPUT *** my routine waits for a keypress -; CMP OLDKY ; KEY IN ACC *** no need to debounce -; BEQ OUT ; (DEBOUNCE) -; STA OLDKY -; - CMP #$43 ; [C] - BNE NOSET ; SET UP - LDX #$1F ; BOARD -WHSET LDA SETW,X ; FROM - STA BOARD,X ; SETW +OUT JSR pout + JSR KIN + CMP #$43 + BNE NOSET + LDX #$1F +WHSET LDA SETW,X + STA BOARD,X DEX BPL WHSET - LDX #$1B ; *ADDED - STX OMOVE ; INITS TO $FF - LDA #$CC ; Display CCC + LDX #$1B + STX OMOVE + LDA #$CC BNE CLDSP -; -NOSET CMP #$45 ; [E] - BNE NOREV ; REVERSE - JSR REVERSE ; BOARD IS +NOSET CMP #$45 + BNE NOREV + JSR REVERSE SEC LDA #$01 SBC REV - STA REV ; TOGGLE REV FLAG - LDA #$EE ; IS + STA REV + LDA #$EE BNE CLDSP -; -NOREV CMP #$40 ; [P] - BNE NOGO ; PLAY CHESS +NOREV CMP #$40 + BNE NOGO JSR GO -CLDSP STA DIS1 ; DISPLAY - STA DIS2 ; ACROSS - STA DIS3 ; DISPLAY +CLDSP STA DIS1 + STA DIS2 + STA DIS3 BNE CHESS -; -NOGO CMP #$0D ; [Enter] - BNE NOMV ; MOVE MAN - JSR MOVE ; AS ENTERED +NOGO CMP #$0D + BNE NOMV + JSR MOVE JMP DISP -NOMV CMP #$41 ; [Q] ***Added to allow game exit*** - BEQ DONE ; quit the game, exit back to system. - JMP INPUT ; process move -DONE JMP $FF00 ; *** MUST set this to YOUR OS starting address -; -; THE ROUTINE JANUS DIRECTS THE -; ANALYSIS BY DETERMINING WHAT -; SHOULD OCCUR AFTER EACH MOVE -; GENERATED BY GNM -; -; -; +NOMV CMP #$41 + BEQ DONE + JMP INPUT +DONE JMP $FF00 + JANUS LDX STATE BMI NOCOUNT -; -; THIS ROUTINE COUNTS OCCURRENCES -; IT DEPENDS UPON STATE TO INDEX -; THE CORRECT COUNTERS -; COUNTS LDA PIECE - BEQ OVER ; IF STATE=8 - CPX #$08 ; DO NOT COUNT - BNE OVER ; BLK MAX CAP - CMP BMAXP ; MOVES FOR - BEQ XRT ; WHITE -; -OVER INC MOB,X ; MOBILITY - CMP #$01 ; + QUEEN - BNE NOQ ; FOR TWO + BEQ OVER + CPX #$08 + BNE OVER + CMP BMAXP + BEQ XRT +OVER INC MOB,X + CMP #$01 + BNE NOQ INC MOB,X -; NOQ BVC NOCAP - LDY #$0F ; CALCULATE - LDA SQUARE ; POINTS -ELOOP CMP BK,Y ; CAPTURED - BEQ FOUN ; BY THIS - DEY ; MOVE + LDY #$0F + LDA SQUARE +ELOOP CMP BK,Y + BEQ FOUN + DEY BPL ELOOP FOUN LDA POINTS,Y CMP MAXC,X - BCC LESS ; SAVE IF - STY PCAP,X ; BEST THIS - STA MAXC,X ; STATE -; + BCC LESS + STY PCAP,X + STA MAXC,X LESS CLC - PHP ; ADD TO - ADC CC,X ; CAPTURE - STA CC,X ; COUNTS + PHP + ADC CC,X + STA CC,X PLP -; NOCAP CPX #$04 BEQ ON4 - BMI TREE ;(=00 ONLY) + BMI TREE XRT RTS -; -; GENERATE FURTHER MOVES FOR COUNT -; AND ANALYSIS -; -ON4 LDA XMAXC ; SAVE ACTUAL - STA WCAP0 ; CAPTURE - LDA #$00 ; STATE=0 +ON4 LDA XMAXC + STA WCAP0 + LDA #$00 STA STATE - JSR MOVE ; GENERATE - JSR REVERSE ; IMMEDIATE - JSR GNMZ ; REPLY MOVES + JSR MOVE JSR REVERSE -; - LDA #$08 ; STATE=8 - STA STATE ; GENERATE -; JSR OHM ; CONTINUATION - JSR UMOVE ; MOVES -; - JMP STRATGY ; FINAL EVALUATION + JSR GNMZ + JSR REVERSE + LDA #$08 + STA STATE + JSR UMOVE + JMP STRATGY NOCOUNT CPX #$F9 BNE TREE -; -; DETERMINE IF THE KING CAN BE -; TAKEN, USED BY CHKCHK -; - LDA BK ; IS KING - CMP SQUARE ; IN CHECK? - BNE RETJ ; SET INCHEK=0 - LDA #$00 ; IF IT IS + LDA BK + CMP SQUARE + BNE RETJ + LDA #$00 STA INCHEK RETJ RTS -; -; IF A PIECE HAS BEEN CAPTURED BY -; A TRIAL MOVE, GENERATE REPLIES & -; EVALUATE THE EXCHANGE GAIN/LOSS -; -TREE BVC RETJ ; NO CAP - LDY #$07 ; (PIECES) +TREE BVC RETJ + LDY #$07 LDA SQUARE LOOPX CMP BK,Y BEQ FOUNX DEY - BEQ RETJ ; (KING) - BPL LOOPX ; SAVE -FOUNX LDA POINTS,Y ; BEST CAP - CMP BCAP0,X ; AT THIS - BCC NOMAX ; LEVEL + BEQ RETJ + BPL LOOPX +FOUNX LDA POINTS,Y + CMP BCAP0,X + BCC NOMAX STA BCAP0,X NOMAX DEC STATE - LDA #$FB ; IF STATE=FB - CMP STATE ; TIME TO TURN - BEQ UPTREE ; AROUND - JSR GENRM ; GENERATE FURTHER -UPTREE INC STATE ; CAPTURES + LDA #$FB + CMP STATE + BEQ UPTREE + JSR GENRM +UPTREE INC STATE RTS -; -; THE PLAYER'S MOVE IS INPUT -; -INPUT CMP #$08 ; NOT A LEGAL - BCS ERROR ; SQUARE # +INPUT CMP #$08 + BCS ERROR JSR DISMV DISP LDX #$1F SEARCH LDA BOARD,X CMP DIS2 - BEQ HERE ; DISPLAY - DEX ; PIECE AT - BPL SEARCH ; FROM -HERE STX DIS1 ; SQUARE + BEQ HERE + DEX + BPL SEARCH +HERE STX DIS1 STX PIECE ERROR JMP CHESS -; -; GENERATE ALL MOVES FOR ONE -; SIDE, CALL JANUS AFTER EACH -; ONE FOR NEXT STE? -; -; -GNMZ LDX #$10 ; CLEAR -GNMX LDA #$00 ; COUNTERS +GNMZ LDX #$10 +GNMX LDA #$00 CLEAR STA COUNT,X DEX BPL CLEAR -; -GNM LDA #$10 ; SET UP - STA PIECE ; PIECE -NEWP DEC PIECE ; NEW PIECE - BPL NEX ; ALL DONE? - RTS ; #NAME? -; -NEX JSR RESET ; READY - LDY PIECE ; GET PIECE +GNM LDA #$10 + STA PIECE +NEWP DEC PIECE + BPL NEX + RTS +NEX JSR RESET + LDY PIECE LDX #$08 - STX MOVEN ; COMMON START - CPY #$08 ; WHAT IS IT? - BPL PAWN ; PAWN + STX MOVEN + CPY #$08 + BPL PAWN CPY #$06 - BPL KNIGHT ; KNIGHT + BPL KNIGHT CPY #$04 - BPL BISHOP ; BISHOP + BPL BISHOP CPY #$01 - BEQ QUEEN ; QUEEN - BPL ROOK ; ROOK -; -KING JSR SNGMV ; MUST BE KING! - BNE KING ; MOVES - BEQ NEWP ; 8 TO 1 + BEQ QUEEN + BPL ROOK +KING JSR SNGMV + BNE KING + BEQ NEWP QUEEN JSR LINE - BNE QUEEN ; MOVES - BEQ NEWP ; 8 TO 1 -; + BNE QUEEN + BEQ NEWP ROOK LDX #$04 - STX MOVEN ; MOVES -AGNR JSR LINE ; 4 TO 1 + STX MOVEN +AGNR JSR LINE BNE AGNR BEQ NEWP -; BISHOP JSR LINE - LDA MOVEN ; MOVES - CMP #$04 ; 8 TO 5 + LDA MOVEN + CMP #$04 BNE BISHOP BEQ NEWP -; KNIGHT LDX #$10 - STX MOVEN ; MOVES -AGNN JSR SNGMV ; 16 TO 9 + STX MOVEN +AGNN JSR SNGMV LDA MOVEN CMP #$08 BNE AGNN BEQ NEWP -; PAWN LDX #$06 STX MOVEN -P1 JSR CMOVE ; RIGHT CAP? +P1 JSR CMOVE BVC P2 BMI P2 - JSR JANUS ; YES + JSR JANUS P2 JSR RESET - DEC MOVEN ; LEFT CAP? + DEC MOVEN LDA MOVEN CMP #$05 BEQ P1 -P3 JSR CMOVE ; AHEAD - BVS NEWP ; ILLEGAL +P3 JSR CMOVE + BVS NEWP BMI NEWP JSR JANUS - LDA SQUARE ; GETS TO - AND #$F0 ; 3RD RANK? + LDA SQUARE + AND #$F0 CMP #$20 - BEQ P3 ; DO DOUBLE + BEQ P3 JMP NEWP -; -; CALCULATE SINGLE STEP MOVES -; FOR K,N -; -SNGMV JSR CMOVE ; CALC MOVE - BMI ILL1 ; -IF LEGAL - JSR JANUS ; -EVALUATE +SNGMV JSR CMOVE + BMI ILL1 + JSR JANUS ILL1 JSR RESET DEC MOVEN RTS -; -; CALCULATE ALL MOVES DOWN A -; STRAIGHT LINE FOR Q,B,R -; -LINE JSR CMOVE ; CALC MOVE - BCC OVL ; NO CHK - BVC LINE ; NOCAP -OVL BMI ILL ; RETURN +LINE JSR CMOVE + BCC OVL + BVC LINE +OVL BMI ILL PHP - JSR JANUS ; EVALUATE POSN + JSR JANUS PLP - BVC LINE ; NOT A CAP -ILL JSR RESET ; LINE STOPPED - DEC MOVEN ; NEXT DIR + BVC LINE +ILL JSR RESET + DEC MOVEN RTS -; -; EXCHANGE SIDES FOR REPLY -; ANALYSIS -; REVERSE LDX #$0F ETC SEC - LDY BK,X ; SUBTRACT - LDA #$77 ; POSITION - SBC BOARD,X ; FROM 77 + LDY BK,X + LDA #$77 + SBC BOARD,X STA BK,X - STY BOARD,X ; AND + STY BOARD,X SEC - LDA #$77 ; EXCHANGE - SBC BOARD,X ; PIECES + LDA #$77 + SBC BOARD,X STA BOARD,X DEX BPL ETC RTS -; -; CMOVE CALCULATES THE TO SQUARE -; USING SQUARE AND THE MOVE -; TABLE FLAGS SET AS FOLLOWS: -; N#NAME? MOVE -; V#NAME? (LEGAL UNLESS IN CR) -; C#NAME? BECAUSE OF CHECK -; [MY &THANKS TO JIM BUTTERFIELD -; WHO WROTE THIS MORE EFFICIENT -; VERSION OF CMOVE) -; -CMOVE LDA SQUARE ; GET SQUARE - LDX MOVEN ; MOVE POINTER + +CMOVE LDA SQUARE + LDX MOVEN CLC - ADC MOVEX,X ; MOVE LIST - STA SQUARE ; NEW POS'N + ADC MOVEX,X + STA SQUARE AND #$88 - BNE ILLEGAL ; OFF BOARD + BNE ILLEGAL LDA SQUARE -; LDX #$20 -LOOP DEX ; IS TO - BMI NO ; SQUARE - CMP BOARD,X ; OCCUPIED? +LOOP DEX + BMI NO + CMP BOARD,X BNE LOOP -; - CPX #$10 ; BY SELF? + CPX #$10 BMI ILLEGAL -; - LDA #$7F ; MUST BE CAP! - ADC #$01 ; SET V FLAG - BVS SPX ; (JMP) -; -NO CLV ; NO CAPTURE -; -SPX LDA STATE ; SHOULD WE - BMI RETL ; DO THE - CMP #$08 ; CHECK CHECK? + LDA #$7F + ADC #$01 + BVS SPX +NO CLV +SPX LDA STATE + BMI RETL + CMP #$08 BPL RETL -; -; CHKCHK REVERSES SIDES -; AND LOOKS FOR A KING -; CAPTURE TO INDICATE -; ILLEGAL MOVE BECAUSE OF -; CHECK SINCE THIS IS -; TIME CONSUMING, IT IS NOT -; ALWAYS DONE -; -CHKCHK PHA ; STATE #392 + +CHKCHK PHA PHP LDA #$F9 - STA STATE ; GENERATE - STA INCHEK ; ALL REPLY - JSR MOVE ; MOVES TO - JSR REVERSE ; SEE IF KING - JSR GNM ; IS IN - JSR RUM ; CHECK + STA STATE + STA INCHEK + JSR MOVE + JSR REVERSE + JSR GNM + JSR RUM PLP PLA STA STATE LDA INCHEK - BMI RETL ; NO - SAFE - SEC ; YES - IN CHK + BMI RETL + SEC LDA #$FF RTS -; -RETL CLC ; LEGAL - LDA #$00 ; RETURN +RETL CLC + LDA #$00 RTS -; ILLEGAL LDA #$FF - CLC ; ILLEGAL - CLV ; RETURN + CLC + CLV RTS -; -; REPLACE PIECE ON CORRECT SQUARE -; -RESET LDX PIECE ; GET LOGAT - LDA BOARD,X ; FOR PIECE - STA SQUARE ; FROM BOARD +RESET LDX PIECE + LDA BOARD,X + STA SQUARE RTS -; -; -; -GENRM JSR MOVE ; MAKE MOVE -GENR2 JSR REVERSE ; REVERSE BOARD - JSR GNM ; GENERATE MOVES -RUM JSR REVERSE ; REVERSE BACK -; -; ROUTINE TO UNMAKE A MOVE MADE BY -; MOVE -; -UMOVE TSX ; UNMAKE MOVE +GENRM JSR MOVE +GENR2 JSR REVERSE + JSR GNM +RUM JSR REVERSE +UMOVE TSX STX SP1 - LDX SP2 ; EXCHANGE - TXS ; STACKS - PLA ; MOVEN + LDX SP2 + TXS + PLA STA MOVEN - PLA ; CAPTURED - STA PIECE ; PIECE + PLA + STA PIECE TAX - PLA ; FROM SQUARE + PLA STA BOARD,X - PLA ; PIECE + PLA TAX - PLA ; TO SOUARE + PLA STA SQUARE STA BOARD,X JMP STRV -; -; THIS ROUTINE MOVES PIECE -; TO SQUARE, PARAMETERS -; ARE SAVED IN A STACK TO UNMAKE -; THE MOVE LATER -; MOVE TSX - STX SP1 ; SWITCH - LDX SP2 ; STACKS + STX SP1 + LDX SP2 TXS LDA SQUARE - PHA ; TO SQUARE + PHA TAY LDX #$1F -CHECK CMP BOARD,X ; CHECK FOR - BEQ TAKE ; CAPTURE +CHECK CMP BOARD,X + BEQ TAKE DEX BPL CHECK TAKE LDA #$CC STA BOARD,X - TXA ; CAPTURED - PHA ; PIECE + TXA + PHA LDX PIECE LDA BOARD,X - STY BOARD,X ; FROM - PHA ; SQUARE + STY BOARD,X + PHA TXA - PHA ; PIECE + PHA LDA MOVEN - PHA ; MOVEN + PHA STRV TSX - STX SP2 ; SWITCH - LDX SP1 ; STACKS - TXS ; BACK + STX SP2 + LDX SP1 + TXS RTS -; -; CONTINUATION OF SUB STRATGY -; -CHECKS FOR CHECK OR CHECKMATE -; AND ASSIGNS VALUE TO MOVE -; -CKMATE LDY BMAXC ; CAN BLK CAP - CPX POINTS ; MY KING? +CKMATE LDY BMAXC + CPX POINTS BNE NOCHEK - LDA #$00 ; GULP! - BEQ RETV ; DUMB MOVE! -; -NOCHEK LDX BMOB ; IS BLACK - BNE RETV ; UNABLE TO - LDX WMAXP ; MOVE AND - BNE RETV ; KING IN CH? - LDA #$FF ; YES! MATE -; -RETV LDX #$04 ; RESTORE - STX STATE ; STATE=4 -; -; THE VALUE OF THE MOVE (IN ACCU) -; IS COMPARED TO THE BEST MOVE AND -; REPLACES IT IF IT IS BETTER -; -PUSH CMP BESTV ; IS THIS BEST - BCC RETP ; MOVE SO FAR? + LDA #$00 + BEQ RETV +NOCHEK LDX BMOB + BNE RETV + LDX WMAXP + BNE RETV + LDA #$FF +RETV LDX #$04 + STX STATE +PUSH CMP BESTV + BCC RETP BEQ RETP - STA BESTV ; YES! - LDA PIECE ; SAVE IT + STA BESTV + LDA PIECE STA BESTP LDA SQUARE - STA BESTM ; FLASH DISPLAY -RETP LDA #"." ; print ... instead of flashing disp - Jmp syschout ; print . and return -; -; MAIN PROGRAM TO PLAY CHESS -; PLAY FROM OPENING OR THINK -; -GO LDX OMOVE ; OPENING? - BMI NOOPEN ; -NO *ADD CHANGE FROM BPL - LDA DIS3 ; -YES WAS - CMP OPNING,X ; OPPONENT'S - BNE END ; MOVE OK? + STA BESTM +RETP LDA #"." + Jmp syschout +GO LDX OMOVE + BMI NOOPEN + LDA DIS3 + CMP OPNING,X + BNE END DEX - LDA OPNING,X ; GET NEXT - STA DIS1 ; CANNED - DEX ; OPENING MOVE LDA OPNING,X - STA DIS3 ; DISPLAY IT + STA DIS1 DEX - STX OMOVE ; MOVE IT - BNE MV2 ; (JMP) -; -END LDA #$FF ; *ADD - STOP CANNED MOVES - STA OMOVE ; FLAG OPENING -NOOPEN LDX #$0C ; FINISHED - STX STATE ; STATE=C - STX BESTV ; CLEAR BESTV - LDX #$14 ; GENERATE P - JSR GNMX ; MOVES -; - LDX #$04 ; STATE=4 - STX STATE ; GENERATE AND - JSR GNMZ ; TEST AVAILABLE -; -; MOVES -; - LDX BESTV ; GET BEST MOVE - CPX #$0F ; IF NONE - BCC MATE ; OH OH! -; -MV2 LDX BESTP ; MOVE - LDA BOARD,X ; THE - STA BESTV ; BEST - STX PIECE ; MOVE + LDA OPNING,X + STA DIS3 + DEX + STX OMOVE + BNE MV2 +END LDA #$FF + STA OMOVE +NOOPEN LDX #$0C + STX STATE + STX BESTV + LDX #$14 + JSR GNMX + LDX #$04 + STX STATE + JSR GNMZ + LDX BESTV + CPX #$0F + BCC MATE +MV2 LDX BESTP + LDA BOARD,X + STA BESTV + STX PIECE LDA BESTM - STA SQUARE ; AND DISPLAY - JSR MOVE ; IT + STA SQUARE + JSR MOVE JMP CHESS -; -MATE LDA #$FF ; RESIGN - RTS ; OR STALEMATE -; -; SUBROUTINE TO ENTER THE -; PLAYER'S MOVE -; -DISMV LDX #$04 ; ROTATE -DROL ASL DIS3 ; KEY - ROL DIS2 ; INTO - DEX ; DISPLAY - BNE DROL ; +MATE LDA #$FF + RTS +DISMV LDX #$04 +DROL ASL DIS3 + ROL DIS2 + DEX + BNE DROL ORA DIS3 STA DIS3 STA SQUARE RTS -; -; THE FOLLOWING SUBROUTINE ASSIGNS -; A VALUE TO THE MOVE UNDER -; CONSIDERATION AND RETURNS IT IN -; THE ACCUMULATOR -; - STRATGY CLC LDA #$80 - ADC WMOB ; PARAMETERS - ADC WMAXC ; WITH WHEIGHT - ADC WCC ; OF O25 + ADC WMOB + ADC WMAXC + ADC WCC ADC WCAP1 ADC WCAP2 SEC @@ -617,38 +413,38 @@ STRATGY CLC SBC BCAP2 SBC PMOB SBC BMOB - BCS POS ; UNDERFLOW - LDA #$00 ; PREVENTION + BCS POS + LDA #$00 POS LSR - CLC ; ************** + CLC ADC #$40 - ADC WMAXC ; PARAMETERS - ADC WCC ; WITH WEIGHT - SEC ; OF 05 + ADC WMAXC + ADC WCC + SEC SBC BMAXC - LSR ; ************** + LSR CLC ADC #$90 - ADC WCAP0 ; PARAMETERS - ADC WCAP0 ; WITH WEIGHT - ADC WCAP0 ; OF 10 + ADC WCAP0 + ADC WCAP0 + ADC WCAP0 ADC WCAP0 ADC WCAP1 - SEC ; [UNDER OR OVER- - SBC BMAXC ; FLOW MAY OCCUR - SBC BMAXC ; FROM THIS - SBC BMCC ; SECTION] + SEC + SBC BMAXC + SBC BMAXC + SBC BMCC SBC BMCC SBC BCAP1 - LDX SQUARE ; *************** + LDX SQUARE CPX #$33 - BEQ POSN ; POSITION - CPX #$34 ; BONUS FOR - BEQ POSN ; MOVE TO - CPX #$22 ; CENTRE - BEQ POSN ; OR - CPX #$25 ; OUT OF - BEQ POSN ; BACK RANK + BEQ POSN + CPX #$34 + BEQ POSN + CPX #$22 + BEQ POSN + CPX #$25 + BEQ POSN LDX PIECE BEQ NOPOSN LDY BOARD,X @@ -656,106 +452,95 @@ POS LSR BPL NOPOSN POSN CLC ADC #$02 -NOPOSN JMP CKMATE ; CONTINUE - - -;----------------------------------------------------------------- -; The following routines were added to allow text-based board -; display over a standard RS-232 port. -; -POUT jsr pout9 ; print CRLF - jsr pout13 ; print copyright - JSR POUT10 ; print column labels - LDY #$00 ; init board location - JSR POUT5 ; print board horz edge -POUT1 lDA #"|" ; print vert edge - JSR syschout ; PRINT ONE ASCII CHR - SPACE +NOPOSN JMP CKMATE +POUT jsr pout9 + jsr pout13 + JSR POUT10 + LDY #$00 + JSR POUT5 +POUT1 lDA #"|" + JSR syschout LDX #$1F -POUT2 TYA ; scan the pieces for a location +POUT2 TYA match - CMP BOARD,X ; match found? - BEQ POUT4 ; yes; print the piece's color and + CMP BOARD,X + BEQ POUT4 type - DEX ; no - BPL POUT2 ; if not the last piece, try again - tya ; empty square - and #$01 ; odd or even column? - sta temp ; save it - tya ; is the row odd or even - lsr ; shift column right 4 spaces - lsr ; - lsr ; - lsr ; - and #$01 ; strip LSB - clc ; - adc temp ; combine row & col to determine + DEX + BPL POUT2 + tya + and #$01 + sta temp + tya + lsr + lsr + lsr + lsr + and #$01 + clc + adc temp square color - and #$01 ; is board square white or blk? - bne pout25 ; white, print space - lda #"*" ; black, print * - .byte $2c ; used to skip over LDA #$20 -POUT25 LDA #$20 ; ASCII space - JSR syschout ; PRINT ONE ASCII CHR - SPACE - JSR syschout ; PRINT ONE ASCII CHR - SPACE -POUT3 INY ; - TYA ; get row number - AND #$08 ; have we completed the row? - BEQ POUT1 ; no, do next column - LDA #"|" ; yes, put the right edge on - JSR syschout ; PRINT ONE ASCII CHR - | - jsr pout12 ; print row number - JSR POUT9 ; print CRLF - JSR POUT5 ; print bottom edge of board - CLC ; - TYA ; - ADC #$08 ; point y to beginning of next row - TAY ; - CPY #$80 ; was that the last row? - BEQ POUT8 ; yes, print the LED values - BNE POUT1 ; no, do new row - -POUT4 LDA REV ; print piece's color & type - BEQ POUT41 ; - LDA cpl+16,X ; - BNE POUT42 ; -POUT41 LDA cpl,x ; -POUT42 JSR syschout ; - lda cph,x ; - jsr syschout ; - BNE POUT3 ; branch always - -POUT5 TXA ; print "-----...-----" + and #$01 + bne pout25 + lda #"*" + .byte $2c +POUT25 LDA #$20 + JSR syschout + JSR syschout +POUT3 INY + TYA + AND #$08 + BEQ POUT1 + LDA #"|" + JSR syschout + jsr pout12 + JSR POUT9 + JSR POUT5 + CLC + TYA + ADC #$08 + TAY + CPY #$80 + BEQ POUT8 + BNE POUT1 +POUT4 LDA REV + BEQ POUT41 + LDA cpl+16,X + BNE POUT42 +POUT41 LDA cpl,x +POUT42 JSR syschout + lda cph,x + jsr syschout + BNE POUT3 +POUT5 TXA PHA LDX #$19 LDA #"-" -POUT6 JSR syschout ; PRINT ONE ASCII CHR - "-" +POUT6 JSR syschout DEX BNE POUT6 PLA TAX JSR POUT9 RTS - -POUT8 jsr pout10 ; +POUT8 jsr pout10 LDA $FB - JSR syshexout ; PRINT 1 BYTE AS 2 HEX CHRS + JSR syshexout LDA #$20 - JSR syschout ; PRINT ONE ASCII CHR - SPACE + JSR syschout LDA $FA - JSR syshexout ; PRINT 1 BYTE AS 2 HEX CHRS + JSR syshexout LDA #$20 - JSR syschout ; PRINT ONE ASCII CHR - SPACE + JSR syschout LDA $F9 - JSR syshexout ; PRINT 1 BYTE AS 2 HEX CHRS - + JSR syshexout POUT9 LDA #$0D - JSR syschout ; PRINT ONE ASCII CHR - CR + JSR syschout LDA #$0A - JSR syschout ; PRINT ONE ASCII CHR - LF + JSR syschout RTS - -pout10 ldx #$00 ; print the column labels -POUT11 lda #$20 ; 00 01 02 03 ... 07 +pout10 ldx #$00 +POUT11 lda #$20 jsr syschout txa jsr syshexout @@ -767,303 +552,238 @@ POUT12 TYA and #$70 JSR syshexout rts - -Pout13 ldx #$00 ; Print the copyright banner +Pout13 ldx #$00 Pout14 lda banner,x beq POUT15 jsr syschout inx bne POUT14 POUT15 rts - KIN LDA #"?" - JSR syschout ; PRINT ONE ASCII CHR - ? - JSR syskin ; GET A KEYSTROKE FROM SYSTEM - AND #$4F ; MASK 0-7, AND ALPHA'S + JSR syschout + JSR syskin + AND #$4F RTS -; -; 6551 I/O Support Routines -; -; -Init_6551 lda #$1F ; 19.2K/8/1 - sta ACIActl ; control reg - lda #$0B ; N parity/echo off/rx int off/ +Init_6551 lda #$1F + sta ACIActl + lda #$0B dtr active low - sta ACIAcmd ; command reg - rts ; done -; -; input chr from ACIA1 (waiting) -; -syskin lda ACIASta ; Serial port status - and #$08 ; is recvr full - beq syskin ; no char to get - Lda ACIAdat ; get chr - RTS ; -; -; output to OutPut Port -; -syschout PHA ; save registers -ACIA_Out1 lda ACIASta ; serial port status - and #$10 ; is tx buffer empty - beq ACIA_Out1 ; no - PLA ; get chr - sta ACIAdat ; put character to Port - RTS ; done - -syshexout PHA ; prints AA hex digits - LSR ; MOVE UPPER NIBBLE TO LOWER - LSR ; - LSR ; - LSR ; - JSR PrintDig ; - PLA ; -PrintDig PHY ; prints A hex nibble (low 4 bits) - AND #$0F ; - TAY ; - LDA Hexdigdata,Y ; - PLY ; - jmp syschout ; - -Hexdigdata .byte "0123456789ABCDEF" -banner .byte "MicroChess (c) 1996-2002 Peter Jennings, -peterj@benlo.com" - .byte $0d, $0a, $00 -cpl .byte "WWWWWWWWWWWWWWWWBBBBBBBBBBBBBBBBWWWWWWWWWWWWWWWW" -cph .byte "KQCCBBRRPPPPPPPPKQCCBBRRPPPPPPPP" - .byte $00 -; -; end of added code -; -; BLOCK DATA - *= $1580 -SETW .byte $03, $04, $00, $07, $02, $05, $01, $06 - .byte $10, $17, $11, $16, $12, $15, $14, $13 - .byte $73, $74, $70, $77, $72, $75, $71, $76 - .byte $60, $67, $61, $66, $62, $65, $64, $63 - -MOVEX .byte $00, $F0, $FF, $01, $10, $11, $0F, $EF, $F1 - .byte $DF, $E1, $EE, $F2, $12, $0E, $1F, $21 - -POINTS .byte $0B, $0A, $06, $06, $04, $04, $04, $04 - .byte $02, $02, $02, $02, $02, $02, $02, $02 - -OPNING .byte $99, $25, $0B, $25, $01, $00, $33, $25 - .byte $07, $36, $34, $0D, $34, $34, $0E, $52 - .byte $25, $0D, $45, $35, $04, $55, $22, $06 - .byte $43, $33, $0F, $CC - -; -; -; end of file - - -TMP EQU $6 ; Temporary storage - + sta ACIAcmd + rts +syskin lda ACIASta + and #$08 + beq syskin + Lda ACIAdat + RTS +syschout PHA +ACIA_Out1 lda ACIASta + and #$10 + beq ACIA_Out1 + PLA + sta ACIAdat + RTS +syshexout PHA + LSR + LSR + LSR + LSR + JSR PrintDig + PLA +PrintDig PHY + AND #$0F + TAY + LDA Hexdigdata,Y + PLY + jmp syschout +TMP EQU $6 WEEKDAY: - CPX #3 ; Year starts in March to bypass - BCS MARCH ; leap year problem - DEY ; If Jan or Feb, decrement year -MARCH EOR #$7F ; Invert A so carry works right - CPY #200 ; Carry will be 1 if 22nd century - ADC MTAB-1,X ; A is now day+month offset + CPX #3 + BCS MARCH + DEY +MARCH EOR #$7F + CPY #200 + ADC MTAB-1,X STA TMP - TYA ; Get the year - JSR MOD7 ; Do a modulo to prevent overflow - SBC TMP ; Combine with day+month + TYA + JSR MOD7 + SBC TMP STA TMP - TYA ; Get the year again - LSR ; Divide it by 4 + TYA LSR - CLC ; Add it to y+m+d and fall through + LSR + CLC ADC TMP -MOD7 ADC #7 ; Returns (A+3) modulo 7 - BCC MOD7 ; for A in 0..255 +MOD7 ADC #7 + BCC MOD7 RTS -MTAB DB 1,5,6,3,1,5,3,0,4,2,6,4 ; Month offsets - -R0L EQU $0 -R0H EQU $1 -R14H EQU $1D -R15L EQU $1E -R15H EQU $1F -SAVE EQU $FF4A -RESTORE EQU $FF3F - - ORG $F689 - AST 32 - - JSR SAVE ;PRESERVE 6502 REG CONTENTS + JSR SAVE PLA - STA R15L ;INIT SWEET16 PC - PLA ;FROM RETURN - STA R15H ;ADDRESS -SW16B JSR SW16C ;INTERPRET AND EXECUTE - JMP SW16B ;ONE SWEET16 INSTR. + STA R15L + PLA + STA R15H +SW16B JSR SW16C + JMP SW16B SW16C INC R15L - BNE SW16D ;INCR SWEET16 PC FOR FETCH + BNE SW16D INC R15H -SW16D LDA >SET ;COMMON HIGH BYTE FOR ALL ROUTINES - PHA ;PUSH ON STACK FOR RTS +SW16D LDA >SET + PHA LDY $0 - LDA (R15L),Y ;FETCH INSTR - AND $F ;MASK REG SPECIFICATION - ASL ;DOUBLE FOR TWO BYTE REGISTERS - TAX ;TO X REG FOR INDEXING + LDA (R15L),Y + AND $F + ASL + TAX LSR - EOR (R15L),Y ;NOW HAVE OPCODE - BEQ TOBR ;IF ZERO THEN NON-REG OP - STX R14H ;INDICATE "PRIOR RESULT REG" + EOR (R15L),Y + BEQ TOBR + STX R14H LSR - LSR ;OPCODE*2 TO LSB'S LSR - TAY ;TO Y REG FOR INDEXING - LDA OPTBL-2,Y ;LOW ORDER ADR BYTE - PHA ;ONTO STACK - RTS ;GOTO REG-OP ROUTINE + LSR + TAY + LDA OPTBL-2,Y + PHA + RTS TOBR INC R15L - BNE TOBR2 ;INCR PC + BNE TOBR2 INC R15H -TOBR2 LDA BRTBL,X ;LOW ORDER ADR BYTE - PHA ;ONTO STACK FOR NON-REG OP - LDA R14H ;"PRIOR RESULT REG" INDEX - LSR ;PREPARE CARRY FOR BC, BNC. - RTS ;GOTO NON-REG OP ROUTINE -RTNZ PLA ;POP RETURN ADDRESS +TOBR2 LDA BRTBL,X + PHA + LDA R14H + LSR + RTS +RTNZ PLA PLA - JSR RESTORE ;RESTORE 6502 REG CONTENTS - JMP (R15L) ;RETURN TO 6502 CODE VIA PC -SETZ LDA (R15L),Y ;HIGH ORDER BYTE OF CONSTANT + JSR RESTORE + JMP (R15L) +SETZ LDA (R15L),Y STA R0H,X DEY - LDA (R15L),Y ;LOW ORDER BYTE OF CONSTANT + LDA (R15L),Y STA R0L,X - TYA ;Y REG CONTAINS 1 + TYA SEC - ADC R15L ;ADD 2 TO PC + ADC R15L STA R15L BCC SET2 INC R15H SET2 RTS -OPTBL DFB SET-1 ;1X -BRTBL DFB RTN-1 ;0 - DFB LD-1 ;2X - DFB BR-1 ;1 - DFB ST-1 ;3X - DFB BNC-1 ;2 - DFB LDAT-1 ;4X - DFB BC-1 ;3 - DFB STAT-1 ;5X - DFB BP-1 ;4 - DFB LDDAT-1 ;6X - DFB BM-1 ;5 - DFB STDAT-1 ;7X - DFB BZ-1 ;6 - DFB POP-1 ;8X - DFB BNZ-1 ;7 - DFB STPAT-1 ;9X - DFB BM1-1 ;8 - DFB ADD-1 ;AX - DFB BNM1-1 ;9 - DFB SUB-1 ;BX - DFB BK-1 ;A - DFB POPD-1 ;CX - DFB RS-1 ;B - DFB CPR-1 ;DX - DFB BS-1 ;C - DFB INR-1 ;EX - DFB NUL-1 ;D - DFB DCR-1 ;FX - DFB NUL-1 ;E - DFB NUL-1 ;UNUSED - DFB NUL-1 ;F - -* FOLLOWING CODE MUST BE -* CONTAINED ON A SINGLE PAGE! - -SET BPL SETZ ;ALWAYS TAKEN +OPTBL DFB SET-1 +BRTBL DFB RTN-1 + DFB LD-1 + DFB BR-1 + DFB ST-1 + DFB BNC-1 + DFB LDAT-1 + DFB BC-1 + DFB STAT-1 + DFB BP-1 + DFB LDDAT-1 + DFB BM-1 + DFB STDAT-1 + DFB BZ-1 + DFB POP-1 + DFB BNZ-1 + DFB STPAT-1 + DFB BM1-1 + DFB ADD-1 + DFB BNM1-1 + DFB SUB-1 + DFB BK-1 + DFB POPD-1 + DFB RS-1 + DFB CPR-1 + DFB BS-1 + DFB INR-1 + DFB NUL-1 + DFB DCR-1 + DFB NUL-1 + DFB NUL-1 + DFB NUL-1 +SET BPL SETZ LD LDA R0L,X BK EQU *-1 STA R0L - LDA R0H,X ;MOVE RX TO R0 + LDA R0H,X STA R0H RTS ST LDA R0L - STA R0L,X ;MOVE R0 TO RX + STA R0L,X LDA R0H STA R0H,X RTS STAT LDA R0L -STAT2 STA (R0L,X) ;STORE BYTE INDIRECT +STAT2 STA (R0L,X) LDY $0 -STAT3 STY R14H ;INDICATE R0 IS RESULT NEG +STAT3 STY R14H INR INC R0L,X - BNE INR2 ;INCR RX + BNE INR2 INC R0H,X INR2 RTS -LDAT LDA (R0L,X) ;LOAD INDIRECT (RX) - STA R0L ;TO R0 +LDAT LDA (R0L,X) + STA R0L LDY $0 - STY R0H ;ZERO HIGH ORDER R0 BYTE - BEQ STAT3 ;ALWAYS TAKEN -POP LDY $0 ;HIGH ORDER BYTE = 0 - BEQ POP2 ;ALWAYS TAKEN -POPD JSR DCR ;DECR RX - LDA (R0L,X) ;POP HIGH ORDER BYTE @RX - TAY ;SAVE IN Y REG -POP2 JSR DCR ;DECR RX - LDA (R0L,X) ;LOW ORDER BYTE - STA R0L ;TO R0 STY R0H -POP3 LDY $0 ;INDICATE R0 AS LAST RESULT REG + BEQ STAT3 +POP LDY $0 + BEQ POP2 +POPD JSR DCR + LDA (R0L,X) + TAY +POP2 JSR DCR + LDA (R0L,X) + STA R0L + STY R0H +POP3 LDY $0 STY R14H RTS -LDDAT JSR LDAT ;LOW ORDER BYTE TO R0, INCR RX - LDA (R0L,X) ;HIGH ORDER BYTE TO R0 +LDDAT JSR LDAT + LDA (R0L,X) STA R0H - JMP INR ;INCR RX -STDAT JSR STAT ;STORE INDIRECT LOW ORDER - LDA R0H ;BYTE AND INCR RX. THEN - STA (R0L,X) ;STORE HIGH ORDER BYTE. - JMP INR ;INCR RX AND RETURN -STPAT JSR DCR ;DECR RX + JMP INR +STDAT JSR STAT + LDA R0H + STA (R0L,X) + JMP INR +STPAT JSR DCR LDA R0L - STA (R0L,X) ;STORE R0 LOW BYTE @RX - JMP POP3 ;INDICATE R0 AS LAST RESULT REG + STA (R0L,X) + JMP POP3 DCR LDA R0L,X - BNE DCR2 ;DECR RX + BNE DCR2 DEC R0H,X DCR2 DEC R0L,X RTS -SUB LDY $0 ;RESULT TO R0 - CPR SEC ;NOTE Y REG = 13*2 FOR CPR +SUB LDY $0 + CPR SEC LDA R0L SBC R0L,X - STA R0L,Y ;R0-RX TO RY + STA R0L,Y LDA R0H SBC R0H,X SUB2 STA R0H,Y - TYA ;LAST RESULT REG*2 - ADC $0 ;CARRY TO LSB + TYA + ADC $0 STA R14H RTS ADD LDA R0L ADC R0L,X - STA R0L ;R0+RX TO R0 + STA R0L LDA R0H ADC R0H,X - LDY $0 ;R0 FOR RESULT - BEQ SUB2 ;FINISH ADD -BS LDA R15L ;NOTE X REG IS 12*2! - JSR STAT2 ;PUSH LOW PC BYTE VIA R12 + LDY $0 + BEQ SUB2 +BS LDA R15L + JSR STAT2 LDA R15H - JSR STAT2 ;PUSH HIGH ORDER PC BYTE + JSR STAT2 BR CLC -BNC BCS BNC2 ;NO CARRY TEST -BR1 LDA (R15L),Y ;DISPLACEMENT BYTE +BNC BCS BNC2 +BR1 LDA (R15L),Y BPL BR2 DEY -BR2 ADC R15L ;ADD TO PC +BR2 ADC R15L STA R15L TYA ADC R15H @@ -1071,174 +791,144 @@ BR2 ADC R15L ;ADD TO PC BNC2 RTS BC BCS BR RTS -BP ASL ;DOUBLE RESULT-REG INDEX - TAX ;TO X REG FOR INDEXING - LDA R0H,X ;TEST FOR PLUS - BPL BR1 ;BRANCH IF SO - RTS -BM ASL ;DOUBLE RESULT-REG INDEX +BP ASL TAX - LDA R0H,X ;TEST FOR MINUS + LDA R0H,X + BPL BR1 + RTS +BM ASL + TAX + LDA R0H,X BMI BR1 RTS -BZ ASL ;DOUBLE RESULT-REG INDEX - TAX - LDA R0L,X ;TEST FOR ZERO - ORA R0H,X ;(BOTH BYTES) - BEQ BR1 ;BRANCH IF SO - RTS -BNZ ASL ;DOUBLE RESULT-REG INDEX - TAX - LDA R0L,X ;TEST FOR NON-ZERO - ORA R0H,X ;(BOTH BYTES) - BNE BR1 ;BRANCH IF SO - RTS -BM1 ASL ;DOUBLE RESULT-REG INDEX - TAX - LDA R0L,X ;CHECK BOTH BYTES - AND R0H,X ;FOR $FF (MINUS 1) - EOR $FF - BEQ BR1 ;BRANCH IF SO - RTS -BNM1 ASL ;DOUBLE RESULT-REG INDEX +BZ ASL TAX LDA R0L,X - AND R0H,X ;CHECK BOTH BYTES FOR NO $FF + ORA R0H,X + BEQ BR1 + RTS +BNZ ASL + TAX + LDA R0L,X + ORA R0H,X + BNE BR1 + RTS +BM1 ASL + TAX + LDA R0L,X + AND R0H,X EOR $FF - BNE BR1 ;BRANCH IF NOT MINUS 1 + BEQ BR1 + RTS +BNM1 ASL + TAX + LDA R0L,X + AND R0H,X + EOR $FF + BNE BR1 NUL RTS -RS LDX $18 ;12*2 FOR R12 AS STACK POINTER - JSR DCR ;DECR STACK POINTER - LDA (R0L,X) ;POP HIGH RETURN ADDRESS TO PC +RS LDX $18 + JSR DCR + LDA (R0L,X) STA R15H - JSR DCR ;SAME FOR LOW ORDER BYTE + JSR DCR LDA (R0L,X) STA R15L RTS RTN JMP RTNZ - .org $f000 init: - lda #$00 ; init output ports of pia 2 - sta mtalock ; reset multitasking lock - lda #$40 ; setup timer for free running + lda #$00 + sta mtalock + lda #$40 sta acr - lda #$c0 ; enable timer interrupts + lda #$c0 sta ier - ldy #0 lda #0 -stinit: sta $100,y ; reset stack to x'00' +stinit: sta $100,y iny bne stinit - - lda #$00 ; set actual task # to 0 + lda #$00 sta mtatask - ldy #maxtask-1 ; get max. number of tasks + ldy #maxtask-1 initloop: - lda mtasini,y ; get initial stackpointer value - sta mtastab,y ; and save value in page 0 table - tax ; move stack pointer value to reg x - lda #$b0 ; set initial flag register contents - sta $0104,x ; save flag register on stack - tya ; get actual task number - asl a ; multiply with 2 - tax ; and move result to reg x - stx mtatemp ; save reg x - lda ent_tab,x ; get pcl-value - ldx mtastab,y ; get stack pointer value - sta $0105,x ; save pcl register on stack - ldx mtatemp ; get reg x - lda ent_tab+1,x ; get pch-value - ldx mtastab,y ; get stack pointer value - sta $0106,x ; save pch register on stack + lda mtasini,y + sta mtastab,y + tax + lda #$b0 + sta $0104,x + tya + asl a + tax + stx mtatemp + lda ent_tab,x + ldx mtastab,y + sta $0105,x + ldx mtatemp + lda ent_tab+1,x + ldx mtastab,y + sta $0106,x dey - bpl initloop ; ==> loop for all tasks - ldx #$3f ; set stack for task 0 + bpl initloop + ldx #$3f txs - - lda #0 ; initial load timer + lda #0 sta t1lsl - lda #40 ; about 1/100 sec timer value + lda #40 sta t1csh - cli ; enable interrupts - jmp ent_task0 ; enter task 0 -;*------------------------------------------------------------------* -;* table of task entry addresses * -;*------------------------------------------------------------------* + cli + jmp ent_task0 ent_tab: .word ent_task0 .word ent_task1 .word ent_task2 .word ent_task3 - -;*------------------------------------------------------------------* -;* program call entry to interrupt service routine * -;*------------------------------------------------------------------* mtaentry: - php ; save processor status on stack -; ; for interrupt simulation - pha ; save registers on current stack + php + pha txa pha tya pha tsx - - inc $105,x ; add 1 to return address - bne mtaent01 ; because of jsr command + inc $105,x + bne mtaent01 inc $106,x mtaent01: - - lda #$00 ; reset task lock + lda #$00 sta mtalock - jmp mtaswitch ; and process task switch - -;*------------------------------------------------------------------* -;* interrupt service routine * -;*------------------------------------------------------------------* + jmp mtaswitch irq: - pha ; save registers on current stack + pha txa pha tya pha - - lda t1csl ; enable interrupt - lda #$c0 ; reset flag + lda t1csl + lda #$c0 sta ifr - - lda mtalock ; is task locked ? - beq mtaswitch ; ==> no, then process task change - inc mtalock ; indicate task switch requested - jmp irq_ret ; ==> and skip task change - -mtaswitch: ; task switcher - ldy mtatask ; get actual task number - tsx ; get actual stack pointer - stx mtastab,y ; and save it in table - iny ; calculate next task number - cpy #maxtask ; valid task number ? - bcc mtanumok ; ==> yes - ldy #0 ; else start with task 0 + lda mtalock + beq mtaswitch + inc mtalock + jmp irq_ret +mtaswitch: + ldy mtatask + tsx + stx mtastab,y + iny + cpy #maxtask + bcc mtanumok + ldy #0 mtanumok: - sty mtatask ; save new task number - ldx mtastab,y ; get new stack pointer - txs ; and load it in sp-register - + sty mtatask + ldx mtastab,y + txs irq_ret: - pla ; load registers from current stack + pla tay pla tax pla - rti ; ==> go and process task - -mtasini .byte $39,$79,$b9,$f9 ; initial stackpointer values -maxtask =$-mtasini - - .org $fffa -nmivector .word init ; nmi vector -resvector .word init ; reset vector -irqvector .word irq ; irq vector + rti .end \ No newline at end of file diff --git a/ref_apl b/ref_apl index e42eb2b..f41151e 100644 --- a/ref_apl +++ b/ref_apl @@ -439,138 +439,6 @@ lam←{ ⍝ See https://dyalog.github.io/Jarvis for documentation (⎕ML ⎕IO)←1 1 - - ∇ r←Version - :Access public shared - r←'Jarvis' '1.14.5' '2023-10-14' - ∇ - - ∇ Documentation - :Access public shared - ⎕←'See https://dyalog.github.io/Jarvis' - ∇ - - ⍝ User hooks settings - :Field Public AppCloseFn←'' ⍝ name of the function to run on application (server) shutdown - :Field Public AppInitFn←'' ⍝ name of the application "bootstrap" function - :Field Public AuthenticateFn←'' ⍝ name of function to perform authentication,if empty, no authentication is necessary - :Field Public SessionInitFn←'' ⍝ Function name to call when initializing a session - :Field Public ValidateRequestFn←'' ⍝ name of the request validation function - - ⍝ Operational settings - :Field Public CodeLocation←'#' ⍝ reference to application code location, if the user specifies a folder or file, that value is saved in CodeSource - :Field Public ConnectionTimeout←30 ⍝ HTTP/1.1 connection timeout in seconds - :Field Public Debug←0 ⍝ 0 = all errors are trapped, 1 = stop on an error, 2 = stop on intentional error before processing request, 4 = Jarvis framework debugging - :Field Public DefaultContentType←'application/json; charset=utf-8' - :Field Public ErrorInfoLevel←1 ⍝ level of information to provide if an APL error occurs, 0=none, 1=⎕EM, 2=⎕SI - :Field Public Hostname←'' ⍝ external-facing host name - :Field Public HTTPAuthentication←'basic' ⍝ valid settings are currently 'basic' or '' - :Field Public JarvisConfig←'' ⍝ configuration file path (if any). This parameter was formerly named ConfigFile - :Field Public LoadableFiles←'*.apl?,*.dyalog' ⍝ file patterns that can be loaded if loading from folder - :Field Public Logging←1 ⍝ turn logging on/off - :Field Public Paradigm←'JSON' ⍝ either 'JSON' or 'REST' - :Field Public Report404InHTML←1 ⍝ Report HTTP 404 status (not found) in HTML (only valid if HTML interface is enabled) - :Field Public UseZip←0 ⍝ Use compression if client allows it, 0- don't compress, 0<- compress if UseZip≤≢payload - :Field Public ZipLevel←3 ⍝ default compression level (0-9) - - ⍝ Container-related settings - :Field Public DYALOG_JARVIS_THREAD←'' ⍝ 0 = Run in thread 0, 1 = Use separate thread and ⎕TSYNC, 'DEBUG' = Use separate thread and return to immediate execution, "AUTO" = if InTerm use "DEBUG" otherwise 1 - :Field Public DYALOG_JARVIS_CODELOCATION←'' ⍝ If supplied, overrides CodeLocation in config file - :Field Public DYALOG_JARVIS_PORT←'' ⍝ If supplied, overrides Port both default port and config file - - ⍝ Session settings - :Field Public SessionIdHeader←'Jarvis-SessionID' ⍝ Name of the header field for the session token - :Field Public SessionUseCookie←0 ⍝ 0 - just use the header; 1 - use an HTTP cookie - :Field Public SessionPollingTime←1 ⍝ how frequently (in minutes) we should poll for timed out sessions - :Field Public SessionTimeout←0 ⍝ 0 = do not use sessions, ¯1 = no timeout , 0< session timeout time (in minutes) - :Field Public SessionCleanupTime←60 ⍝ how frequently (in minutes) do we clean up timed out session info from _sessionsInfo - - ⍝ JSON mode settings - :Field Public AllowFormData←0 ⍝ do we allow POST form data in JSON paradigm? - :Field Public AllowGETs←0 ⍝ do we allow calling endpoints with HTTP GETs? - :Field Public HTMLInterface←¯1 ⍝ ¯1=unassigned, 0/1=dis/allow the HTML interface, 'Path to HTML[/home-page]', or '' 'fn' - :Field Public JSONInputFormat←'D' ⍝ set this to 'M' to have Jarvis convert JSON request payloads to the ⎕JSON matrix format - - ⍝ REST mode settings - :Field Public ParsePayload←1 ⍝ 1=parse request payload based on content-type header (REST only) - :Field Public RESTMethods←'Get,Post,Put,Delete,Patch,Options' - - ⍝ CORS settings - :Field Public EnableCORS←1 ⍝ set to 0 to disable CORS - :Field Public CORS_Origin←'*' ⍝ default value for Access-Control-Allow-Origin header (set to 1 to reflect request Origin) - :Field Public CORS_Methods←¯1 ⍝ ¯1 = set based on paradigm, 1 = reflect the request's requested method - :Field Public CORS_Headers←'*' ⍝ default value for Access-Control-Allow-Headers header (set to 1 to reflect request Headers) - :Field Public CORS_MaxAge←60 ⍝ default value (in seconds) for Access-Control-Max-Age header - - ⍝ Conga-related settings - :Field Public AcceptFrom←⍬ ⍝ Conga: IP addresses to accept requests from - empty means accept from any IP address - :Field Public BufferSize←10000 ⍝ Conga: buffer size - :Field Public DenyFrom←⍬ ⍝ Conga: IP addresses to refuse requests from - empty means deny none - :Field Public DOSLimit←¯1 ⍝ Conga: DOSLimit, ¯1 means use default - :Field Public Port←8080 ⍝ Conga: Default port to listen on - :Field Public RootCertDir←'' ⍝ Conga: Root CA certificate folder - :field Public Priority←'NORMAL:!CTYPE-OPENPGP' ⍝ Conga: Priorities for GnuTLS when negotiation connection - :Field Public Secure←0 ⍝ 0 = use HTTP, 1 = use HTTPS - :field Public ServerCertSKI←'' ⍝ Conga: Server cert's Subject Key Identifier from store - :Field Public ServerCertFile←'' ⍝ Conga: public certificate file - :Field Public ServerKeyFile←'' ⍝ Conga: private key file - :Field Public ServerName←'' ⍝ Server name, '' means Conga assigns it - :Field Public SSLValidation←64 ⍝ Conga: request, but do not require a client certificate - :Field Public WaitTimeout←15000 ⍝ ms to wait in LDRC.Wait - - :Field Public Shared LDRC←'' ⍝ Jarvis-set reference to Conga after CongaRef has been resolved - :Field Public Shared CongaPath←'' ⍝ user-supplied path to Conga workspace and/or shared libraries - :Field Public Shared CongaRef←'' ⍝ user-supplied reference to Conga library instance - :Field CongaVersion←'' ⍝ Conga version - - :Property CodeSource - :Access Public - ∇ r←get - r←_codeSource - ∇ - :EndProperty - - ⍝ IncludeFns/ExcludeFns Properties - :Property IncludeFns, ExcludeFns - ⍝ IncludeFns and ExcludeFns are vectors the defined endpoint (function) names to expose or hide respectively - ⍝ They can be function names, simple wildcarded patterns (e.g. 'Foo*'), or regex - :Access Public - ∇ r←get ipa - r←⍎'_',ipa.Name - ∇ - ∇ set ipa - :Select ipa.Name - :Case 'IncludeFns' - _includeRegex←makeRegEx¨(⊂'')~⍨∪,⊆_IncludeFns←ipa.NewValue - :Case 'ExcludeFns' - _excludeRegex←makeRegEx¨(⊂'')~⍨∪,⊆_ExcludeFns←ipa.NewValue - :EndSelect - ∇ - :EndProperty - - ⍝↓↓↓ some of these private fields are also set in ∇init so that a server can be stopped, updated, and restarted - :Field _rootFolder←'' ⍝ root folder for relative file paths - :Field _codeSource←'' ⍝ file or folder that code was loaded from, if applicable - :Field _configLoaded←0 ⍝ indicates whether config was already loaded by Autostart - :Field _htmlFolder←'' ⍝ folder containing HTML interface files, if any - :Field _htmlDefaultPage←'index.html' ⍝ default page name if HTMLInterface is set to serve from a folder - :Field _htmlEnabled←0 ⍝ is the HTML interface enabled? - :Field _htmlRootFn←'' ⍝ function name if serving HTML root from a function rather than file - :Field _stop←0 ⍝ set to 1 to stop server - :Field _started←0 ⍝ is the server started - :Field _stopped←1 ⍝ is the server stopped - :field _paused←0 ⍝ is the server paused - :Field _sessionThread←¯1 ⍝ thread for the session cleanup process - :Field _serverThread←¯1 ⍝ thread for the HTTP server - :Field _taskThreads←⍬ ⍝ vector of thread handling requests - :Field _sessions←⍬ ⍝ vector of session namespaces - :Field _sessionsInfo←0 5⍴'' '' 0 0 0 ⍝ [;1] id [;2] ip addr [;3] creation time [;4] last active time [;5] ref to session - :Field _IncludeFns←'' ⍝ private IncludeFns - :Field _ExcludeFns←'' ⍝ private ExcludeFns - :Field _includeRegex←'' ⍝ private compiled regex from _IncludeFns - :Field _excludeRegex←'' ⍝ private compiled regex from _ExcludeFns - :Field _connections ⍝ namespace containing open connections - ∇ r←Config ⍝ returns current configuration :Access public @@ -1713,33 +1581,6 @@ lam←{ ∇ :class Request - :Field Public Instance AcceptEncodings←''⍝ content-encodings that the client will accept - :Field Public Instance Boundary←'' ⍝ boundary for content-type 'multipart/form-data' - :Field Public Instance Charset←'' ⍝ content charset (defaults to 'utf-8' if content-type is application/json) - :Field Public Instance Complete←0 ⍝ do we have a complete request? - :Field Public Instance ContentType←'' ⍝ content-type header value - :Field Public Instance Cookies←0 2⍴⊂'' ⍝ cookie name/value pairs - :Field Public Instance Input←'' - :Field Public Instance Headers←0 2⍴⊂'' ⍝ HTTPRequest header fields (plus any supplied from HTTPTrailer event) - :Field Public Instance Method←'' ⍝ HTTP method (GET, POST, PUT, etc) - :Field Public Instance Endpoint←'' ⍝ Requested URI - :Field Public Instance Body←'' ⍝ body of the request - :Field Public Instance Payload←'' ⍝ parsed (if JSON or XML) payload - :Field Public Instance PeerAddr←'unknown'⍝ client IP address - :Field Public Instance PeerCert←0 0⍴⊂'' ⍝ client certificate - :Field Public Instance HTTPVersion←'' - :Field Public Instance ErrorInfoLevel←1 - :Field Public Instance Response - :Field Public Instance Server - :Field Public Instance Session←⍬ - :Field Public Instance QueryParams←0 2⍴0 - :Field Public Instance UserID←'' - :Field Public Instance Password←'' - :Field Public Shared HttpStatus←↑(200 'OK')(201 'Created')(204 'No Content')(301 'Moved Permanently')(302 'Found')(303 'See Other')(304 'Not Modified')(305 'Use Proxy')(307 'Temporary Redirect')(400 'Bad Request')(401 'Unauthorized')(403 'Forbidden')(404 'Not Found')(405 'Method Not Allowed')(406 'Not Acceptable')(408 'Request Timeout')(409 'Conflict')(410 'Gone')(411 'Length Required')(412 'Precondition Failed')(413 'Request Entity Too Large')(414 'Request-URI Too Long')(415 'Unsupported Media Type')(500 'Internal Server Error')(501 'Not Implemented')(503 'Service Unavailable') - - ⍝ Content types for common file extensions - :Field Public Shared ContentTypes←18 2⍴'txt' 'text/plain' 'htm' 'text/html' 'html' 'text/html' 'css' 'text/css' 'xml' 'text/xml' 'svg' 'image/svg+xml' 'json' 'application/json' 'zip' 'application/x-zip-compressed' 'csv' 'text/csv' 'pdf' 'application/pdf' 'mp3' 'audio/mpeg' 'pptx' 'application/vnd.openxmlformats-officedocument.presentationml.presentation' 'js' 'application/javascript' 'png' 'image/png' 'jpg' 'image/jpeg' 'bmp' 'image/bmp' 'jpeg' 'image/jpeg' 'woff' 'application/font-woff' - GetFromTable←{(⍵[;1]⍳⊂,⍺)⊃⍵[;2],⊂''} split←{p←(⍺⍷⍵)⍳1 ⋄ ((p-1)↑⍵)(p↓⍵)} ⍝ Split ⍵ on first occurrence of ⍺ lc←0∘(819⌶) @@ -1895,7 +1736,6 @@ lam←{ ∇ base64←{⎕IO ⎕ML←0 1 ⍝ from dfns workspace - Base64 encoding and decoding as used in MIME. - chars←'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' bits←{,⍉(⍺⍴2)⊤⍵} ⍝ encode each element of ⍵ in ⍺ bits, and catenate them all together part←{((⍴⍵)⍴⍺↑1)⊂⍵} ⍝ partition ⍵ into chunks of length ⍺ 0=2|⎕DR ⍵:2∘⊥∘(8∘↑)¨8 part{(-8|⍴⍵)↓⍵}6 bits{(⍵≠64)/⍵}chars⍳⍵ ⍝ decode a string into octets @@ -1965,19 +1805,6 @@ lam←{ Response.Headers⍪←name(∊⍕value) ∇ - ∇ {(name cookie)}←name SetCookie cookie - :Access public instance - ⍝ create a response "set-cookie" header - ⍝ cookie is the cookie value followed by any ;-delimited attributes - 'set-cookie'SetHeader name,'=',cookie - ∇ - - ∇ {(name value)}←SetContentType contentType - :Access public instance - ⍝ shortcut function to set the response content-type header - (name value)←'Content-Type'SetHeader contentType - ∇ - ∇ value←GetCookie name :Access public instance ⍝ retrieve a request cookie @@ -2005,41 +1832,6 @@ lam←{ :Section SessionHandler - ∇ InitSessions - ⍝ initialize session handling - :If 0≠SessionTimeout ⍝ are we using sessions? - _sessions←⍬ - _sessionsInfo←0 5⍴0 ⍝ [;1] id, [;2] IP address, [;3] creation time, [;4] last active time, [;5] ref to session - ⎕RL←⍬ - :If 0 means no timeout and sessions are managed by the application - _sessionThread←SessionMonitor&SessionTimeout - :EndIf - :EndIf - ∇ - - ∇ SessionMonitor timeout;expired;dead - :Repeat - :If 0<≢_sessionsInfo - :Hold 'Sessions' - :If ∨/expired←SessionTimeout IsExpired _sessionsInfo[;4] ⍝ any expired? - ⍝ ↓↓↓ if a session expires, remove the namespace from _sessions - ⍝ but leave the entry in _sessionsInfo (removing the namespace reference) - ⍝ so that we can report to the user that his session timed out - ⍝ if he returns before SessionCleanupTime passes - _sessions~←expired/_sessionsInfo[;5] ⍝ remove from sessions list - (expired/_sessionsInfo[;5])←0 ⍝ remove reference from _sessionsInfo - :EndIf - ⍝ ↓↓↓ SessionCleanupTime is used to clean up _sessionsInfo after a session has expired - ⍝ In general SessionCleanupTime should be set to a value ≥ SessionTimeout - :If ∨/dead←(0=_sessionsInfo[;5])∧SessionCleanupTime IsExpired _sessionsInfo[;4] ⍝ any expired sessions need their info removed? - _sessionsInfo⌿⍨←~dead ⍝ remove from _sessionsInfo - :EndIf - :EndHold - :EndIf - {}⎕DL timeout×60 - :EndRepeat - ∇ - MakeSessionId←{⎕IO←0 ⋄((0(819⌶)⎕A),⎕A,⎕D)[(?20⍴62),5↑1↓⎕TS]} IsExpired←{⍺≤0: 0 ⋄ (Now-⍵)>(⍺×60000)÷86400000} @@ -2048,92 +1840,6 @@ lam←{ r←(2 ⎕NQ'.' 'DateToIDN'(3↑ts))+(0 60 60 1000⊥¯4↑7↑ts)÷86400000 ∇ - ∇ CreateSession req;ref;now;id;ts;rc - id←MakeSessionId'' - now←Now - :Hold 'Sessions' - _sessions,←ref←⎕NS'' - _sessionsInfo⍪←id req.PeerAddr now now ref - req.Session←ref - :EndHold - :If ~0∊⍴SessionInitFn - :If 3=CodeLocation.⎕NC SessionInitFn - :Trap 0 DebugLevel 1 - :Trap 85 - stopIf DebugLevel 2 - rc←SessionInitFn CodeLocation.{1(85⌶)⍺,' ⍵'}req - :Else ⋄ rc←0 - :EndTrap - - :If 0≠rc - (_sessions _sessionsInfo)←¯1↓¨_sessions _sessionsInfo - →0⊣('Session intialization returned ',⍕rc)req.Fail 500 - :EndIf - :Else - →0⊣(⎕DMX.EM,' occurred during session initialization failed')req.Fail 500 - :EndTrap - :Else - →0⊣('Session initialization function "',SessionInitFn,'" not found')req.Fail 500 - :EndIf - :EndIf - :If SessionUseCookie - SessionIdHeader req.SetCookie id,(SessionTimeout>0)/'; Max-Age=',⍕⌈60×SessionTimeout - :Else - SessionIdHeader req.SetHeader id - :EndIf - ∇ - - ∇ r←KillSession id;ind - ⍝ forcibly kill a session - ⍝ r is 1 if session was killed, 0 if not found - :Hold 'Sessions' - :If r←(≢_sessionsInfo)≥ind←_sessionsInfo[;1]⍳⊆id - _sessions~←_sessionsInfo[ind;5] - _sessionsInfo⌿⍨←ind≠⍳≢_sessionsInfo - :EndIf - :EndHold - ∇ - - ∇ req TimeoutSession ind - ⍝ assumes :Hold 'Sessions' is set in calling environment - ⍝ removes session from _sessions and marks it as time out in _sessionsInfo - _sessions~←_sessionsInfo[ind;5] - _sessionsInfo⌿←ind≠⍳≢_sessionsInfo - ∇ - - ∇ id←GetSessionId req - :If SessionUseCookie - id←req.GetCookie SessionIdHeader - :Else - id←req.GetHeader SessionIdHeader - :EndIf - ∇ - - ∇ r←CheckSession req;ind;session;timedOut;id - ⍝ check for valid session (only called if SessionTimeout≠0) - r←1 - :Hold 'Sessions' - id←GetSessionId req - ind←_sessionsInfo[;1]⍳⊂id - →0⍴⍨ind>≢_sessionsInfo - - :If 0∊⍴session←⊃_sessionsInfo[ind;5] ⍝ already timed out (session was already removed from _sessions) - :OrIf SessionTimeout IsExpired _sessionsInfo[ind;4] ⍝ newly expired - req TimeoutSession ind - →0 - :EndIf - ⍝ we have a valid session, refresh the cookie or set the header - :If SessionUseCookie - SessionIdHeader req.SetCookie id,(SessionTimeout>0)/'; Max-Age=',⍕⌈60×SessionTimeout - :ElseIf - SessionIdHeader req.SetHeader id - :EndIf - _sessionsInfo[ind;4]←Now - req.Session←session - r←0 - :EndHold - ∇ - :EndSection :Section Utilities @@ -2154,10 +1860,6 @@ lam←{ sins←{0∊⍴⍺:⍵ ⋄ ⍺} ⍝ set if not set stopIf←{1∊⍵:-⎕TRAP←0 'C' '⎕←''Stopped for debugging... (Press Ctrl-Enter)''' ⋄ shy←0} ⍝ faster alternative to setting ⎕STOP show←{(2⊃⎕SI),'[',(⍕2⊃⎕LC),'] ',⍵} ⍝ debugging utility - utf8←{3=10|⎕DR ⍵: 256|⍵ ⋄ 'UTF-8' ⎕UCS ⍵} - fromutf8←{0::(⎕AV,'?')[⎕AVU⍳⍵] ⋄ 'UTF-8'⎕UCS ⍵} ⍝ Turn raw UTF-8 input into text - sint←{⎕IO←0 ⋄ 83=⎕DR ⍵:⍵ ⋄ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 ¯128 ¯127 ¯126 ¯125 ¯124 ¯123 ¯122 ¯121 ¯120 ¯119 ¯118 ¯117 ¯116 ¯115 ¯114 ¯113 ¯112 ¯111 ¯110 ¯109 ¯108 ¯107 ¯106 ¯105 ¯104 ¯103 ¯102 ¯101 ¯100 ¯99 ¯98 ¯97 ¯96 ¯95 ¯94 ¯93 ¯92 ¯91 ¯90 ¯89 ¯88 ¯87 ¯86 ¯85 ¯84 ¯83 ¯82 ¯81 ¯80 ¯79 ¯78 ¯77 ¯76 ¯75 ¯74 ¯73 ¯72 ¯71 ¯70 ¯69 ¯68 ¯67 ¯66 ¯65 ¯64 ¯63 ¯62 ¯61 ¯60 ¯59 ¯58 ¯57 ¯56 ¯55 ¯54 ¯53 ¯52 ¯51 ¯50 ¯49 ¯48 ¯47 ¯46 ¯45 ¯44 ¯43 ¯42 ¯41 ¯40 ¯39 ¯38 ¯37 ¯36 ¯35 ¯34 ¯33 ¯32 ¯31 ¯30 ¯29 ¯28 ¯27 ¯26 ¯25 ¯24 ¯23 ¯22 ¯21 ¯20 ¯19 ¯18 ¯17 ¯16 ¯15 ¯14 ¯13 ¯12 ¯11 ¯10 ¯9 ¯8 ¯7 ¯6 ¯5 ¯4 ¯3 ¯2 ¯1[utf8 ⍵]} - Zipper←219⌶ ∇ r←DyalogRoot r←{⍵,('/\'∊⍨⊢/⍵)↓'/'}{0∊⍴t←2 ⎕NQ'.' 'GetEnvironment' 'DYALOG':⊃1 ⎕NPARTS⊃2 ⎕NQ'.' 'GetCommandLineArgs' ⋄ t}'' @@ -2172,15 +1874,6 @@ lam←{ :EndTrap ∇ - ∇ r←crlf - r←⎕UCS 13 10 - ∇ - - ∇ QuadOFF - ⍝ cover for ⎕OFF in case we want to add debugging - ⎕OFF - ∇ - ∇ r←Now r←DateToIDNX ⎕TS ∇ @@ -2324,9 +2017,6 @@ lam←{ ∇ Deserialise←{ -⍝ copied (and modified to work here) from -⍝ https://github.com/Dyalog/qSE/tree/db88297980476d81e0122624ecaa246c94149555 - ⍝ Convert text to array ⍺←⍬ ⍝ 1=execute expression; 0=return expression ⎕IO←0 @@ -2389,21 +2079,6 @@ lam←{ assns/⍨←~quadMask ∊'({'(assns,¨'⋄')quadAssns'⎕NS'('(, '∘,¨q,¨names,¨⊂q')')'}⍬)' } - Execute←{ ⍝ overcome LIMIT ERROR on more than 4096 parenthesised expressions - ExecuteEach←{ ⍝ split at level-1 parentheses and execute each - l←(t=¯1)++\t←{1 ¯1 0['()'⍳⍵]}Unquot ⍵ ⍝ parenthesis type and level - (h x t l)←(1 0 0 0=⊂∧\l=0)/¨⍵ ⍵ t l ⍝ extract header before first opening parenthesis - ⍺{0::0 ⋄ r←⍺⍎⍵ ⋄ ~(⊃⎕NC'r')∊3 4}h:⍺⍎⍵ ⍝ header must be an functional expression - H←⍺{⍺⍺⍎⍵⍵,'⍵'}h ⍝ function to apply header to array - ' '∨.≠(l=0)/x:⍺⍎⍵ ⍝ something outside level-1 parentheses - must fall back to ⍎ - x←(((l>0)∧(l≠1)∨(t=0))×+\(t=1)∧(l=1))⊆x ⍝ cut expression within level-1 parentheses - 1=≢x:H ⍺ ∇⊃x ⍝ single expression : don't enclose with ¨ - DEBUG∧1<⌈/l:H ⍺ ∇¨x ⍝ force going through the hard code - 10::H ⍺ ∇¨x ⋄ H ⍺⍎¨x ⍝ attempt to ⍎¨ with a single guard - otherwise dig each - } - DEBUG:⍺ ExecuteEach ⍵ ⍝ force going through the hard code - 10::⍺ ExecuteEach ⍵ ⋄ ⍺⍎⍵ ⍝ attempt simple ⍎ and catch LIMIT ERROR - } ⍝ Make normalised simple vector: w←↓⍣(2=≢⍴⍵)⊢⍵ ⍝ if mat, make nested w←{¯1↓∊⍵,¨⎕UCS 13}⍣(2=|≡w)⊢w ⍝ if nested, make simple @@ -2438,84 +2113,6 @@ lam←{ ∇ r←HtmlPage;endpoints :Access public r←ScriptFollows -⍝ -⍝ -⍝ -⍝ -⍝ -⍝Jarvis -⍝ -⍝ -⍝ -⍝
-⍝
-⍝ Request -⍝
-⍝
-⍝ -⍝ ⍠ -⍝
-⍝
-⍝ -⍝ -⍝
-⍝
-⍝ -⍝
-⍝
-⍝
-⍝
-⍝ Response -⍝
-⍝
-⍝
-⍝ -⍝
-⍝ -⍝ endpoints←{⍵/⍨0=CheckFunctionName ⍵}EndPoints CodeLocation :If 0∊⍴endpoints endpoints←'No Endpoints Found' diff --git a/ref_c b/ref_c index 8de4586..8bbdffa 100644 --- a/ref_c +++ b/ref_c @@ -1,7 +1,7 @@ #include #include -#include "common.h" +#include uint16_t Q; @@ -60,7 +60,7 @@ static vector(struct label_t) fixup_labels(vector(struct instruction_t) program, if(it->type == LBL) { struct _label_t * l; if((l = getlabel(labels, it->label)) != NULL) { - warn("duplicated label."); + warn(); vector_free(it->label); it->data = l->id; continue; @@ -81,7 +81,7 @@ static vector(struct label_t) fixup_labels(vector(struct instruction_t) program, it->data = l->id; } else { vector_free(it->label); - warn("dead label."); + warn(); it->data = 0; } } @@ -113,7 +113,7 @@ struct parse_result_t parse(FILE * input, void (*fatal)(char * s), void (*warn)( vector_push_back(q, cur = parse_io(input, fatal)); break; default: - fatal("? , E, IMP N/A"); return (struct parse_result_t) { NULL, NULL }; + fatal(); return (struct parse_result_t) { NULL, NULL }; } break; case ' ': @@ -139,8 +139,8 @@ struct parse_result_t parse(FILE * input, void (*fatal)(char * s), void (*warn)( #include #include -#include "vector.h" -#include "common.h" +#include +#include static void append_code(char ** buf, char * format, ...) { va_list args, args2; @@ -342,7 +342,7 @@ static hashmap* hashmap_create(void) m->first = NULL; /* this prevents branching in hashmap_set. - * m->first will be treated as the "next" pointer in an imaginary bucket. + * m->first will be treated as the pointer in an imaginary bucket. * when the first item is added, m->first will be set to the correct address. */ m->last = (struct bucket*)&m->first; @@ -576,11 +576,11 @@ static void hashmap_iterate(hashmap* m, hashmap_callback c, void* user_ptr) #include #include -#include "../include/config.h" -#include "../include/runzip.h" -#include "../include/rzip.h" -#include "../include/stream.h" -#include "../include/util.h" +#include +#include +#include +#include +#include #define MAGIC_LEN (20) // new v 0.9 magic header #define MAGIC_V8_LEN (18) // new v 0.8 magic header @@ -594,7 +594,7 @@ static i64 fdout_seekto(rzip_control * control, i64 pos) { pos -= control->out_relofs; control->out_ofs = pos; if (unlikely(pos > control->out_len || pos < 0)) { - print_err("Trying to seek to %'" PRId64 " outside tmp outbuf in fdout_seekto\n", pos); + print_err(, pos); return -1; } @@ -620,10 +620,10 @@ i64 get_ram(rzip_control * control) { /* Raise limits all the way to the max */ - if (getrlimit(RLIMIT_DATA, &rl) == -1) fatal(("Failed to get limits in get_ram\n"), -1); + if (getrlimit(RLIMIT_DATA, &rl) == -1) fatal((), -1); rl.rlim_cur = rl.rlim_max; - if (setrlimit(RLIMIT_DATA, &rl) == -1) fatal(("Failed to set limits in get_ram\n"), -1); + if (setrlimit(RLIMIT_DATA, &rl) == -1) fatal((), -1); /* Declare detected RAM to be either the max RAM available from physical memory or the max RAM allowed by RLIMIT_DATA, whatever @@ -641,19 +641,19 @@ i64 get_ram(rzip_control * control) { ramsize = (i64)sysconf(_SC_PHYS_PAGES) * PAGE_SIZE; if (ramsize <= 0) { /* Workaround for uclibc which doesn't properly support sysconf */ - if (!(meminfo = fopen("/proc/meminfo", "r"))) fatal("Failed to open /proc/meminfo\n"); + if (!(meminfo = fopen(); - while (!feof(meminfo) && !fscanf(meminfo, "MemTotal: %" PRId64 " kB", &ramsize)) { + while (!feof(meminfo) && !fscanf(meminfo, , &ramsize)) { if (unlikely(fgets(aux, sizeof(aux), meminfo) == NULL)) { fclose(meminfo); - fatal("Failed to fgets in get_ram\n"); + fatal(); } } - if (fclose(meminfo) == -1) fatal("Failed to close /proc/meminfo\n"); + if (fclose(meminfo) == -1) fatal(); ramsize *= 1024; } #endif - if (ramsize <= 0) fatal("No memory or can't determine ram? Can't continue.\n"); + if (ramsize <= 0) fatal(); return ramsize; } @@ -718,14 +718,14 @@ bool write_magic(rzip_control * control) { /* store comment length */ magic[19] = (char)control->comment_length; - if (unlikely(fdout_seekto(control, 0))) fatal("Failed to seek to BOF to write Magic Header\n"); + if (unlikely(fdout_seekto(control, 0))) fatal(); - if (unlikely(put_fdout(control, magic, MAGIC_LEN) != MAGIC_LEN)) fatal("Failed to write magic header\n"); + if (unlikely(put_fdout(control, magic, MAGIC_LEN) != MAGIC_LEN)) fatal(); /* now write comment if any */ if (magic[19]) { if (unlikely(put_fdout(control, control->comment, control->comment_length) != control->comment_length)) - fatal("Failed to write comment after magic header\n"); + fatal(); } control->magic_written = 1; @@ -738,9 +738,9 @@ static inline i64 enc_loops(uchar b1, uchar b2) { return (i64)b2 << (i64)b1; } // Called only if comment length > 0 static void get_comment(rzip_control * control, int fd_in, unsigned char * magic) { - if (unlikely(!(control->comment = malloc(magic[19] + 1)))) fatal("Failed to allocate memory for comment\n"); + if (unlikely(!(control->comment = malloc(magic[19] + 1)))) fatal(); /* read comment */ - if (unlikely(read(fd_in, control->comment, magic[19]) != magic[19])) fatal("Failed to read comment\n"); + if (unlikely(read(fd_in, control->comment, magic[19]) != magic[19])) fatal(); control->comment_length = magic[19]; control->comment[control->comment_length] = '\0'; @@ -758,7 +758,7 @@ static void get_hash_from_magic(rzip_control * control, unsigned char * magic) { control->hash_gcode = &hashes[control->hash_code].gcode; control->hash_len = &hashes[control->hash_code].length; } else - print_verbose("Unknown hash, falling back to CRC\n"); + print_verbose(); return; } @@ -776,7 +776,7 @@ static void get_encryption(rzip_control * control, unsigned char * magic, unsign control->st_size = 0; control->encloops = enc_loops(control->salt[0], control->salt[1]); } else if (ENCRYPT) { - print_err("Asked to decrypt a non-encrypted archive. Bypassing decryption. May fail!\n"); + print_err(); control->flags &= ~FLAG_ENCRYPT; control->enc_code = 0; } @@ -855,7 +855,7 @@ static bool get_magic(rzip_control * control, int fd_in, unsigned char * magic) get_magic_v9(control, fd_in, magic); break; default: - print_err("mrzip version %d.%d archive is not supported. Aborting\n", control->major_version, + print_err(, control->major_version, control->minor_version); return false; } @@ -870,9 +870,9 @@ static bool read_magic(rzip_control * control, int fd_in, i64 * expected_size) { memset(magic, 0, sizeof(magic)); /* Initially read only file type and version */ - if (unlikely(read(fd_in, magic, MAGIC_HEADER) != MAGIC_HEADER)) fatal("Failed to read initial magic header\n"); + if (unlikely(read(fd_in, magic, MAGIC_HEADER) != MAGIC_HEADER)) fatal(); - if (unlikely(strncmp(magic, "MRZI", 4))) fatal("Not an mrzip file\n"); + if (unlikely(strncmp(magic, ); if (magic[4] == 0) { if (magic[5] < 8) /* old magic */ @@ -883,7 +883,7 @@ static bool read_magic(rzip_control * control, int fd_in, i64 * expected_size) { bytes_to_read = MAGIC_LEN; if (unlikely(read(fd_in, &magic[6], bytes_to_read - MAGIC_HEADER) != bytes_to_read - MAGIC_HEADER)) - fatal("Failed to read magic header\n"); + fatal(); } if (unlikely(!get_magic(control, fd_in, magic))) return false; @@ -895,20 +895,20 @@ static bool read_magic(rzip_control * control, int fd_in, i64 * expected_size) { * helps preserve output format when validating */ static void show_version(rzip_control * control) { - print_verbose("Detected mrzip version %'d.%'d file.\n", control->major_version, control->minor_version); + print_verbose(, control->major_version, control->minor_version); } /* preserve ownership and permissions where possible */ static bool preserve_perms(rzip_control * control, int fd_in, int fd_out) { struct stat st; - if (unlikely(fstat(fd_in, &st))) fatal("Failed to fstat input file\n"); + if (unlikely(fstat(fd_in, &st))) fatal(); if (unlikely(fchmod(fd_out, (st.st_mode & 0666)))) - print_verbose("Warning, unable to set permissions on %s\n", control->outfile); + print_verbose(, control->outfile); /* chown fail is not fatal_return(( */ if (unlikely(fchown(fd_out, st.st_uid, st.st_gid))) - print_verbose("Warning, unable to set owner on %s\n", control->outfile); + print_verbose(, control->outfile); return true; } @@ -916,11 +916,11 @@ static bool preserve_times(rzip_control * control, int fd_in) { struct utimbuf times; struct stat st; - if (unlikely(fstat(fd_in, &st))) fatal("Failed to fstat input file\n"); + if (unlikely(fstat(fd_in, &st))) fatal(); times.actime = 0; times.modtime = st.st_mtime; if (unlikely(utime(control->outfile, ×))) - print_verbose("Warning, unable to set time on %s\n", control->outfile); + print_verbose(, control->outfile); return true; } @@ -929,14 +929,14 @@ static bool preserve_times(rzip_control * control, int fd_in) { int open_tmpoutfile(rzip_control * control) { int fd_out; - if (STDOUT && !TEST_ONLY) print_verbose("Outputting to stdout.\n"); + if (STDOUT && !TEST_ONLY) print_verbose(); control->outfile = realloc(NULL, strlen(control->tmpdir) + 16); - if (unlikely(!control->outfile)) fatal("Failed to allocate outfile name\n"); + if (unlikely(!control->outfile)) fatal(); strcpy(control->outfile, control->tmpdir); - strcat(control->outfile, "mrzipout.XXXXXX"); + strcat(control->outfile, ); fd_out = mkstemp(control->outfile); - if (fd_out == -1) fatal("Failed to create out tmpfile: %s\n", control->outfile); + if (fd_out == -1) fatal(, control->outfile); register_outfile(control, control->outfile, TEST_ONLY || STDOUT || !KEEP_BROKEN); return fd_out; @@ -951,7 +951,7 @@ static bool fwrite_stdout(rzip_control * control, void * buf, i64 len) { while (len > 0) { nmemb = len; ret = fwrite(offset_buf, 1, nmemb, control->outFILE); - if (unlikely(ret == -1)) fatal("Failed to fwrite %'" PRId64 " bytes in fwrite_stdout\n", nmemb); + if (unlikely(ret == -1)) fatal(, nmemb); len -= ret; offset_buf += ret; total += ret; @@ -969,7 +969,7 @@ bool write_fdout(rzip_control * control, void * buf, i64 len) { ret = write(control->fd_out, offset_buf, (size_t)nmemb); /* error if ret == -1 only. Otherwise, buffer not wholly written */ if (unlikely(ret == -1)) /* error, not underflow */ - fatal("Failed to write %'" PRId64 " bytes to fd_out in write_fdout\n", nmemb); + fatal(, nmemb); len -= ret; offset_buf += ret; } @@ -978,7 +978,7 @@ bool write_fdout(rzip_control * control, void * buf, i64 len) { bool flush_tmpoutbuf(rzip_control * control) { if (!TEST_ONLY) { - print_maxverbose("Dumping buffer to physical file.\n"); + print_maxverbose(); if (STDOUT) { if (unlikely(!fwrite_stdout(control, control->tmp_outbuf, control->out_len))) return false; } else { @@ -995,21 +995,21 @@ bool dump_tmpoutfile(rzip_control * control, int fd_out) { FILE * tmpoutfp; int tmpchar; - if (unlikely(fd_out == -1)) fatal("Failed: No temporary outfile created, unable to do in ram\n"); + if (unlikely(fd_out == -1)) fatal(); /* flush anything not yet in the temporary file */ fsync(fd_out); - tmpoutfp = fdopen(fd_out, "r"); - if (unlikely(tmpoutfp == NULL)) fatal("Failed to fdopen out tmpfile\n"); + tmpoutfp = fdopen(fd_out, ); + if (unlikely(tmpoutfp == NULL)) fatal(); rewind(tmpoutfp); if (!TEST_ONLY) { - print_verbose("Dumping temporary file to control->outFILE.\n"); + print_verbose(); while ((tmpchar = fgetc(tmpoutfp)) != EOF) putchar(tmpchar); fflush(control->outFILE); rewind(tmpoutfp); } - if (unlikely(ftruncate(fd_out, 0))) fatal("Failed to ftruncate fd_out in dump_tmpoutfile\n"); + if (unlikely(ftruncate(fd_out, 0))) fatal(); return true; } @@ -1023,7 +1023,7 @@ bool write_fdin(rzip_control * control) { while (len > 0) { ret = len; ret = write(control->fd_in, offset_buf, (size_t)ret); - if (unlikely(ret == -1)) fatal("Failed to write to fd_in in write_fdin\n"); + if (unlikely(ret == -1)) fatal(); len -= ret; offset_buf += ret; } @@ -1036,19 +1036,19 @@ int open_tmpinfile(rzip_control * control) { /* Use temporary directory if there is one. /tmp is default */ control->infile = malloc(strlen(control->tmpdir) + 15); - if (unlikely(!control->infile)) fatal("Failed to allocate infile name\n"); + if (unlikely(!control->infile)) fatal(); strcpy(control->infile, control->tmpdir); - strcat(control->infile, "mrzipin.XXXXXX"); + strcat(control->infile, ); fd_in = mkstemp(control->infile); - if (fd_in == -1) fatal("Failed to create in tmpfile: %s\n", control->infile); + if (fd_in == -1) fatal(, control->infile); register_infile(control, control->infile, (DECOMPRESS || TEST_ONLY) && STDIN); /* Unlink temporary file immediately to minimise chance of files left * lying around */ if (unlikely(unlink(control->infile))) { close(fd_in); - fatal("Failed to unlink tmpfile: %s\n", control->infile); + fatal(, control->infile); } return fd_in; } @@ -1062,11 +1062,11 @@ static bool read_tmpinmagic(rzip_control * control, int fd_in) { /* Initially read only file type and version */ for (i = 0; i < MAGIC_HEADER; i++) { tmpchar = getchar(); - if (unlikely(tmpchar == EOF)) fatal("Reached end of file on STDIN prematurely on magic read\n"); + if (unlikely(tmpchar == EOF)) fatal(); magic[i] = (char)tmpchar; } - if (unlikely(strncmp(magic, "MRZI", 4))) fatal("Not an mrzip stream\n"); + if (unlikely(strncmp(magic, ); if (magic[4] == 0) { if (magic[5] < 8) /* old magic */ @@ -1078,7 +1078,7 @@ static bool read_tmpinmagic(rzip_control * control, int fd_in) { for (; i < bytes_to_read; i++) { tmpchar = getchar(); - if (unlikely(tmpchar == EOF)) fatal("Reached end of file on STDIN prematurely on magic read\n"); + if (unlikely(tmpchar == EOF)) fatal(); magic[i] = (char)tmpchar; } } @@ -1092,9 +1092,9 @@ bool read_tmpinfile(rzip_control * control, int fd_in) { int tmpchar; if (fd_in == -1) return false; - if (control->flags & FLAG_SHOW_PROGRESS) fprintf(control->msgout, "Copying from stdin.\n"); - tmpinfp = fdopen(fd_in, "w+"); - if (unlikely(tmpinfp == NULL)) fatal("Failed to fdopen in tmpfile\n"); + if (control->flags & FLAG_SHOW_PROGRESS) fprintf(control->msgout, ); + tmpinfp = fdopen(fd_in, ); + if (unlikely(tmpinfp == NULL)) fatal(); while ((tmpchar = getchar()) != EOF) fputc(tmpchar, tmpinfp); @@ -1113,11 +1113,11 @@ static bool open_tmpoutbuf(rzip_control * control) { round_to_page(&maxlen); buf = malloc(maxlen); if (buf) { - print_maxverbose("Malloced %'" PRId64 " for tmp_outbuf\n", maxlen); + print_maxverbose(, maxlen); break; } maxlen = maxlen / 3 * 2; - if (maxlen < 100000000) fatal("Unable to even malloc 100MB for tmp_outbuf\n"); + if (maxlen < 100000000) fatal(); } control->flags |= FLAG_TMP_OUTBUF; /* Allocate slightly more so we can cope when the buffer overflows and @@ -1141,15 +1141,15 @@ static bool open_tmpinbuf(rzip_control * control) { control->flags |= FLAG_TMP_INBUF; control->in_maxlen = control->maxram; control->tmp_inbuf = malloc(control->maxram + control->page_size); - if (unlikely(!control->tmp_inbuf)) fatal("Failed to malloc tmp_inbuf in open_tmpinbuf\n"); + if (unlikely(!control->tmp_inbuf)) fatal(); return true; } void clear_tmpinbuf(rzip_control * control) { control->in_len = control->in_ofs = 0; } bool clear_tmpinfile(rzip_control * control) { - if (unlikely(lseek(control->fd_in, 0, SEEK_SET))) fatal("Failed to lseek on fd_in in clear_tmpinfile\n"); - if (unlikely(ftruncate(control->fd_in, 0))) fatal("Failed to truncate fd_in in clear_tmpinfile\n"); + if (unlikely(lseek(control->fd_in, 0, SEEK_SET))) fatal(); + if (unlikely(ftruncate(control->fd_in, 0))) fatal(); return true; } @@ -1167,12 +1167,12 @@ static int get_pass(rzip_control * control, char * s) { if (control->passphrase) strncpy(s, control->passphrase, PASS_LEN - SALT_LEN - 1); else if (unlikely(fgets(s, PASS_LEN - SALT_LEN, stdin) == NULL)) - fatal("Failed to retrieve passphrase\n"); + fatal(); len = strlen(s); if (len > 0 && ('\r' == s[len - 1] || '\n' == s[len - 1])) s[len - 1] = '\0'; if (len > 1 && ('\r' == s[len - 2] || '\n' == s[len - 2])) s[len - 2] = '\0'; len = strlen(s); - if (unlikely(0 == len)) fatal("Empty passphrase\n"); + if (unlikely(0 == len)) fatal(); return len; } @@ -1190,7 +1190,7 @@ static bool get_hash(rzip_control * control, int make_hash) { dealloc(passphrase); dealloc(control->salt_pass); dealloc(control->hash); - fatal("Failed to calloc encrypt buffers in get_hash\n"); + fatal(); } mlock(passphrase, PASS_LEN); mlock(testphrase, PASS_LEN); @@ -1203,15 +1203,15 @@ static bool get_hash(rzip_control * control, int make_hash) { termios_p.c_lflag &= ~ECHO; tcsetattr(fileno(stdin), 0, &termios_p); retry_pass: - if (prompt) print_output("Enter passphrase: "); + if (prompt) print_output(); control->salt_pass_len = get_pass(control, passphrase) + SALT_LEN; - if (prompt) print_output("\n"); + if (prompt) print_output(); if (make_hash) { - if (prompt) print_output("Re-enter passphrase: "); + if (prompt) print_output(); get_pass(control, testphrase); - if (prompt) print_output("\n"); + if (prompt) print_output(); if (strcmp(passphrase, testphrase)) { - print_output("Passwords do not match. Try again.\n"); + print_output(); goto retry_pass; } } @@ -1245,9 +1245,9 @@ bool get_header_info(rzip_control * control, int fd_in, uchar * ctype, i64 * c_l // read in salt // first 8 bytes, instead of chunk bytes and size if (unlikely(read(fd_in, enc_head, SALT_LEN) != SALT_LEN)) - fatal("Failed to read encrypted header in get_header_info\n"); + fatal(); } - if (unlikely(read(fd_in, ctype, 1) != 1)) fatal("Failed to read in get_header_info\n"); + if (unlikely(read(fd_in, ctype, 1) != 1)) fatal(); *c_len = *u_len = *last_head = 0; /* remove checks for mrzip < 0.6 */ @@ -1256,16 +1256,16 @@ bool get_header_info(rzip_control * control, int fd_in, uchar * ctype, i64 * c_l int read_len; read_len = chunk_bytes; - if (unlikely(read(fd_in, c_len, read_len) != read_len)) fatal("Failed to read in get_header_info\n"); - if (unlikely(read(fd_in, u_len, read_len) != read_len)) fatal("Failed to read in get_header_info\n"); - if (unlikely(read(fd_in, last_head, read_len) != read_len)) fatal("Failed to read_i64 in get_header_info\n"); + if (unlikely(read(fd_in, c_len, read_len) != read_len)) fatal(); + if (unlikely(read(fd_in, u_len, read_len) != read_len)) fatal(); + if (unlikely(read(fd_in, last_head, read_len) != read_len)) fatal(); *c_len = le64toh(*c_len); *u_len = le64toh(*u_len); *last_head = le64toh(*last_head); if (ENCRYPT) { // decrypt header suppressing printing max verbose message if (unlikely(!decrypt_header(control, enc_head, ctype, c_len, u_len, last_head, LRZ_VALIDATE))) - fatal("Failed to decrypt header in get_header_info\n"); + fatal(); } } // control->major_version return true; @@ -1305,17 +1305,17 @@ bool get_fileinfo(rzip_control * control) { struct stat fdin_stat; if (unlikely(stat(control->infile, &fdin_stat))) - fatal("File %s not found...\n", control->infile); + fatal(, control->infile); else if (unlikely(!S_ISREG(fdin_stat.st_mode))) - fatal("File %s us not a regular file. mrzip cannot continue...\n", control->infile); + fatal(, control->infile); else infilecopy = strdupa(control->infile); fd_in = open(infilecopy, O_RDONLY); - if (unlikely(fd_in == -1)) fatal("Failed to open %s\n", infilecopy); + if (unlikely(fd_in == -1)) fatal(, infilecopy); /* Get file size */ - if (unlikely(fstat(fd_in, &st))) fatal("bad magic file descriptor!?\n"); + if (unlikely(fstat(fd_in, &st))) fatal(); infile_size = st.st_size; /* Get decompressed size */ @@ -1333,14 +1333,14 @@ bool get_fileinfo(rzip_control * control) { /* remove checks for mrzip < 0.6 */ if (control->major_version == 0) { - if (unlikely(read(fd_in, &chunk_byte, 1) != 1)) fatal("Failed to read chunk_byte in get_fileinfo\n"); - if (unlikely(chunk_byte < 1 || chunk_byte > 8)) fatal("Invalid chunk bytes %'d\n", chunk_byte); - if (unlikely(read(fd_in, &control->eof, 1) != 1)) fatal("Failed to read eof in get_fileinfo\n"); + if (unlikely(read(fd_in, &chunk_byte, 1) != 1)) fatal(); + if (unlikely(chunk_byte < 1 || chunk_byte > 8)) fatal(, chunk_byte); + if (unlikely(read(fd_in, &control->eof, 1) != 1)) fatal(); if (!ENCRYPT) { if (unlikely(read(fd_in, &chunk_size, chunk_byte) != chunk_byte)) - fatal("Failed to read chunk_size in get_fileinfo\n"); + fatal(); chunk_size = le64toh(chunk_size); - if (unlikely(chunk_size < 0)) fatal("Invalid chunk size %'" PRId64 "\n", chunk_size); + if (unlikely(chunk_size < 0)) fatal(, chunk_size); /* set header offsets for earlier versions */ switch (control->minor_version) { case 9: @@ -1361,7 +1361,7 @@ bool get_fileinfo(rzip_control * control) { ofs = 22 + control->comment_length; break; default: - fatal("Cannot decrypt earlier versions of mrzip\n"); + fatal(); break; } } @@ -1375,71 +1375,71 @@ next_chunk: if (!ENCRYPT) { chunk_total += chunk_size; - if (unlikely(chunk_byte && (chunk_byte > 8 || chunk_size <= 0))) fatal("Invalid chunk data\n"); + if (unlikely(chunk_byte && (chunk_byte > 8 || chunk_size <= 0))) fatal(); } if (INFO) { - print_verbose("Rzip chunk: %'d\n", ++chunk); - print_verbose("Chunk byte width: %'d\n", chunk_byte); - print_verbose("Chunk size: "); + print_verbose(, ++chunk); + print_verbose(, chunk_byte); + print_verbose(); if (!ENCRYPT) - print_verbose("%'" PRId64 "\n", chunk_size); + print_verbose(, chunk_size); else - print_verbose("N/A %s Encrypted File\n", control->enc_label); + print_verbose(, control->enc_label); } while (stream < NUM_STREAMS) { int block = 1; second_last = 0; if (unlikely(lseek(fd_in, stream_head[stream] + ofs, SEEK_SET) == -1)) - fatal("Failed to seek to header data in get_fileinfo\n"); + fatal(); if (unlikely(!get_header_info(control, fd_in, &ctype, &c_len, &u_len, &last_head, chunk_byte))) return false; if (ENCRYPT && ctype != CTYPE_NONE) - fatal("Invalid stream ctype (%02x) for encrypted file. Bad Password?\n", ctype); + fatal(, ctype); if (INFO) { - print_verbose("Stream: %'d\n", stream); - print_maxverbose("Offset: %'" PRId64 "\n", stream_head[stream] + ofs); - print_verbose("%s\t%s\t%s\t%16s / %14s", "Block", "Comp", "Percent", "Comp Size", "UComp Size"); - print_maxverbose("%18s : %14s", "Offset", "Head"); - print_verbose("\n"); + print_verbose(, stream); + print_maxverbose(, stream_head[stream] + ofs); + print_verbose(); + print_maxverbose(); + print_verbose(); } do { i64 head_off; if (unlikely(last_head && last_head <= second_last)) - fatal("Invalid earlier last_head position, corrupt archive.\n"); + fatal(); second_last = last_head; if (!ENCRYPT) { if (unlikely(last_head + ofs > infile_size)) - fatal("Offset greater than archive size, likely corrupted/truncated archive.\n"); + fatal(); } else { if (unlikely(last_head + ofs + header_length > infile_size)) - fatal("Offset greater than archive size, likely corrupted/truncated archive.\n"); + fatal(); } if (unlikely((head_off = lseek(fd_in, last_head + ofs, SEEK_SET)) == -1)) - fatal("Failed to seek to header data in get_fileinfo\n"); + fatal(); if (unlikely(!get_header_info(control, fd_in, &ctype, &c_len, &u_len, &last_head, chunk_byte))) return false; - if (unlikely(last_head < 0 || c_len < 0 || u_len < 0)) fatal("Entry negative, likely corrupted archive.\n"); - if (INFO) print_verbose("%'d\t", block); + if (unlikely(last_head < 0 || c_len < 0 || u_len < 0)) fatal(); + if (INFO) print_verbose(, block); if (ctype == CTYPE_NONE) { - if (INFO) print_verbose("none"); + if (INFO) print_verbose(); } else if (ctype == CTYPE_LZ4) { - if (INFO) print_verbose("lz4"); + if (INFO) print_verbose(); } else if (ctype == CTYPE_LZMA) { - if (INFO) print_verbose("lzma"); + if (INFO) print_verbose(); } else if (ctype == CTYPE_ZSTD) { - if (INFO) print_verbose("zstd"); + if (INFO) print_verbose(); } else if (ctype == CTYPE_ZPAQ) { - if (INFO) print_verbose("zpaq"); + if (INFO) print_verbose(); } else if (ctype == CTYPE_BZIP3) { - if (INFO) print_verbose("bzip3"); + if (INFO) print_verbose(); } else - fatal("Unknown Compression Type: %'d\n", ctype); + fatal(, ctype); if (save_ctype == 255) save_ctype = ctype; /* need this for lzma when some chunks could have no compression * and info will show rzip + none on info display if last chunk @@ -1448,16 +1448,16 @@ next_chunk: utotal += u_len; ctotal += c_len; if (INFO) { - print_verbose("\t%5.1f%%\t%'16" PRId64 " / %'14" PRId64 "", percentage(c_len, u_len), c_len, u_len); - print_maxverbose("%'18" PRId64 " : %'14" PRId64 "", head_off, last_head); - print_verbose("\n"); + print_verbose(, percentage(c_len, u_len), c_len, u_len); + print_maxverbose(, head_off, last_head); + print_verbose(); } block++; } while (last_head); ++stream; } - if (unlikely((ofs = lseek(fd_in, c_len, SEEK_CUR)) == -1)) fatal("Failed to lseek c_len in get_fileinfo\n"); + if (unlikely((ofs = lseek(fd_in, c_len, SEEK_CUR)) == -1)) fatal(); if (ofs >= infile_size - *control->hash_len) goto done; @@ -1468,14 +1468,14 @@ next_chunk: /* remove checks for mrzip < 0.6 */ if (control->major_version == 0) { if (!ENCRYPT) { - if (unlikely(read(fd_in, &chunk_byte, 1) != 1)) fatal("Failed to read chunk_byte in get_fileinfo\n"); - if (unlikely(chunk_byte < 1 || chunk_byte > 8)) fatal("Invalid chunk bytes %'d\n", chunk_byte); + if (unlikely(read(fd_in, &chunk_byte, 1) != 1)) fatal(); + if (unlikely(chunk_byte < 1 || chunk_byte > 8)) fatal(, chunk_byte); ofs++; - if (unlikely(read(fd_in, &control->eof, 1) != 1)) fatal("Failed to read eof in get_fileinfo\n"); + if (unlikely(read(fd_in, &control->eof, 1) != 1)) fatal(); if (unlikely(read(fd_in, &chunk_size, chunk_byte) != chunk_byte)) - fatal("Failed to read chunk_size in get_fileinfo\n"); + fatal(); chunk_size = le64toh(chunk_size); - if (unlikely(chunk_size < 0)) fatal("Invalid chunk size %'" PRId64 "\n", chunk_size); + if (unlikely(chunk_size < 0)) fatal(, chunk_size); ofs += 1 + chunk_byte; header_length = 1 + (chunk_byte * 3); } else { @@ -1491,73 +1491,73 @@ done: /* compression ratio and bits per byte ratio */ cratio = (long double)expected_size / (long double)infile_size; bpb = ((long double)infile_size / (long double)expected_size) * 8; - if (unlikely(ofs > infile_size)) fatal("Offset greater than archive size, likely corrupted/truncated archive.\n"); + if (unlikely(ofs > infile_size)) fatal(); if (INFO) { - print_output("\nSummary\n=======\n"); - print_output("File: %s\nmrzip version: %'d.%'d ", infilecopy, control->major_version, control->minor_version, - ENCRYPT ? "Encrypted " : ""); - if (ENCRYPT) print_output("%s Encrypted ", control->enc_label); - print_output("file\n"); + print_output(); + print_output(, infilecopy, control->major_version, control->minor_version, + ENCRYPT ? ); + if (ENCRYPT) print_output(, control->enc_label); + print_output(); if (control->comment_length) /* print comment */ - print_output("Archive Comment: %s\n", control->comment); + print_output(, control->comment); - print_output("Compression Method: "); + print_output(); if (save_ctype == CTYPE_NONE) - print_output("rzip alone\n"); + print_output(); else if (save_ctype == CTYPE_LZ4) - print_output("rzip + lz4\n"); + print_output(); else if (save_ctype == CTYPE_LZMA) { - print_output("rzip + lzma"); + print_output(); } else if (save_ctype == CTYPE_ZSTD) - print_output("rzip + zstd\n"); + print_output(); else if (save_ctype == CTYPE_ZPAQ) { - print_output("rzip + zpaq "); + print_output(); if (control->zpaq_level) // update magic with zpaq coding. - print_output("-- Compression Level = %d, Block Size = %d, %'dMB\n", control->zpaq_level, + print_output(, control->zpaq_level, control->zpaq_bs, (1 << control->zpaq_bs)); else // early 0.8 or <0.8 file without zpaq coding in magic header - print_output("\n"); + print_output(); } else if (save_ctype == BZIP3_COMPRESS) { - print_output("rzip + bzip3 -- Block Size: %d - %'" PRIu32 "\n", control->bzip3_bs, + print_output(, control->bzip3_bs, control->bzip3_block_size); } else - print_output("Dunno wtf\n"); + print_output(); /* only print stored compression level for versions that have it! */ if (control->compression_level) - print_output("Rzip Compression Level: %d, Lrzip-next Compressinn Level: %d\n", + print_output(, control->rzip_compression_level, control->compression_level); if (!expected_size) - print_output("Due to using %s, expected decompression size not available\n", - ENCRYPT ? "Encryption" : "Compression to STDOUT"); + print_output(, + ENCRYPT ? ); print_verbose( - " Stats Percent Compressed / Uncompressed\n " - "-------------------------------------------------------\n"); + + ); /* If we can't show expected size, tailor output for it */ if (expected_size) { - print_verbose(" Rzip: %5.1f%%\t%'16" PRId64 " / %'14" PRId64 "\n", + print_verbose(, percentage(utotal, expected_size), utotal, expected_size); - print_verbose(" Back end: %5.1f%%\t%'16" PRId64 " / %'14" PRId64 "\n", percentage(ctotal, utotal), + print_verbose(, percentage(ctotal, utotal), ctotal, utotal); - print_verbose(" Overall: %5.1f%%\t%'16" PRId64 " / %'14" PRId64 "\n", + print_verbose(, percentage(ctotal, expected_size), ctotal, expected_size); } else { - print_verbose(" Rzip: Unavailable\n"); - print_verbose(" Back end: %5.1f%%\t%'16" PRId64 " / %'14" PRId64 "\n", percentage(ctotal, utotal), + print_verbose(); + print_verbose(, percentage(ctotal, utotal), ctotal, utotal); - print_verbose(" Overall: Unavailable\n"); + print_verbose(); } if (expected_size) { - print_output("\n Decompressed file size: %'14" PRIu64 "\n", expected_size); - print_output(" Compressed file size: %'14" PRIu64 "\n", infile_size); - print_output(" Compression ratio: %14.3Lfx, bpb: %.3Lf\n", cratio, bpb); + print_output(, expected_size); + print_output(, infile_size); + print_output(, cratio, bpb); } else { - print_output(" Decompressed file size: Unavailable\n"); - print_output(" Compressed file size: %'14" PRIu64 "\n", infile_size); - print_output(" Compression ratio: Unavailable\n"); + print_output(); + print_output(, infile_size); + print_output(); } } /* end if (INFO) */ @@ -1569,23 +1569,23 @@ done: if (INFO) { hash_stored = calloc(*control->hash_len, 1); if (unlikely(lseek(fd_in, -*control->hash_len, SEEK_END) == -1)) - fatal("Failed to seek to %s data in get_fileinfo.\n", control->hash_label); + fatal(, control->hash_label); if (unlikely(read(fd_in, hash_stored, *control->hash_len) != *control->hash_len)) - fatal("Failed to read %s data in get_fileinfo.\n", control->hash_label); + fatal(, control->hash_label); if (ENCRYPT) if (unlikely(!lrz_decrypt(control, hash_stored, *control->hash_len, control->salt_pass, LRZ_VALIDATE))) - fatal("Failure decrypting %s in get_fileinfo.\n", control->hash_label); - print_output("\n %s Checksum: ", control->hash_label); - for (i = 0; i < *control->hash_len; i++) print_output("%02x", hash_stored[i]); - print_output("\n"); + fatal(, control->hash_label); + print_output(, control->hash_label); + for (i = 0; i < *control->hash_len; i++) print_output(, hash_stored[i]); + print_output(); dealloc(hash_stored); } } else { - if (INFO) print_output("\n CRC32 used for integrity testing\n"); + if (INFO) print_output(); } out: - if (unlikely(close(fd_in))) fatal("Failed to close fd_in in get_fileinfo\n"); + if (unlikely(close(fd_in))) fatal(); return true; error: dealloc(control->outfile); @@ -1614,7 +1614,7 @@ bool compress_file(rzip_control * control) { if (!STDIN) { fd_in = open(control->infile, O_RDONLY); - if (unlikely(fd_in == -1)) fatal("Failed to open %s\n", control->infile); + if (unlikely(fd_in == -1)) fatal(, control->infile); } else fd_in = fileno(control->inFILE); @@ -1633,7 +1633,7 @@ bool compress_file(rzip_control * control) { control->outfile = malloc((control->outdir == NULL ? 0 : strlen(control->outdir)) + strlen(tmpinfile) + strlen(control->suffix) + 1); - if (unlikely(!control->outfile)) fatal("Failed to allocate outfile name\n"); + if (unlikely(!control->outfile)) fatal(); if (control->outdir) { /* prepend control->outdir */ strcpy(control->outfile, control->outdir); @@ -1641,23 +1641,23 @@ bool compress_file(rzip_control * control) { } else strcpy(control->outfile, tmpinfile); strcat(control->outfile, control->suffix); - // print_progress("Output filename is: %s\n", control->outfile); + // print_progress(, control->outfile); // Not needed since printed at end of decompression } if (!strcmp(control->infile, control->outfile)) - fatal("Input and Output files are the same. %s. Exiting\n", control->infile); + fatal(, control->infile); fd_out = open(control->outfile, O_RDWR | O_CREAT | O_EXCL, 0666); if (FORCE_REPLACE && (-1 == fd_out) && (EEXIST == errno)) { - if (unlikely(unlink(control->outfile))) fatal("Failed to unlink an existing file: %s\n", control->outfile); + if (unlikely(unlink(control->outfile))) fatal(, control->outfile); fd_out = open(control->outfile, O_RDWR | O_CREAT | O_EXCL, 0666); } if (unlikely(fd_out == -1)) { /* We must ensure we don't delete a file that already * exists just because we tried to create a new one */ control->flags |= FLAG_KEEP_BROKEN; - fatal("Failed to create %s\n", control->outfile); + fatal(, control->outfile); } control->fd_out = fd_out; if (!STDIN) { @@ -1668,7 +1668,7 @@ bool compress_file(rzip_control * control) { } /* Write zeroes to header at beginning of file */ - if (unlikely(!STDOUT && write(fd_out, header, len) != len)) fatal("Cannot write file header\n"); + if (unlikely(!STDOUT && write(fd_out, header, len) != len)) fatal(); rzip_fd(control, fd_in, fd_out); @@ -1680,20 +1680,20 @@ bool compress_file(rzip_control * control) { if (ENCRYPT) release_hashes(control); if (unlikely(!STDIN && !STDOUT && !preserve_times(control, fd_in))) { - fatal("Failed to preserve times on output file\n"); + fatal(); goto error; } if (unlikely(close(fd_in))) { - fatal("Failed to close fd_in\n"); + fatal(); fd_in = -1; goto error; } - if (unlikely(!STDOUT && close(fd_out))) fatal("Failed to close fd_out\n"); + if (unlikely(!STDOUT && close(fd_out))) fatal(); if (TMP_OUTBUF) close_tmpoutbuf(control); if (!KEEP_FILES && !STDIN) { - if (unlikely(unlink(control->infile))) fatal("Failed to unlink %s\n", control->infile); + if (unlikely(unlink(control->infile))) fatal(, control->infile); } dealloc(control->outfile); @@ -1720,9 +1720,9 @@ bool decompress_file(rzip_control * control) { struct stat fdin_stat; infilecopy = strdupa(control->infile); if (unlikely(stat(infilecopy, &fdin_stat))) - fatal("File %s not found...\n", control->infile); + fatal(, control->infile); else if (unlikely(!S_ISREG(fdin_stat.st_mode))) - fatal("mrzip only works on regular FILES\n"); + fatal(); /* regardless, infilecopy has the input filename */ } @@ -1744,7 +1744,7 @@ bool decompress_file(rzip_control * control) { if ((tmp = strrchr(tmpoutfile, '.')) && !strcmp(tmp, control->suffix)) *tmp = '\0'; control->outfile = malloc((control->outdir == NULL ? 0 : strlen(control->outdir)) + strlen(tmpoutfile) + 1); - if (unlikely(!control->outfile)) fatal("Failed to allocate outfile name\n"); + if (unlikely(!control->outfile)) fatal(); if (control->outdir) { /* prepend control->outdir */ strcpy(control->outfile, control->outdir); @@ -1753,24 +1753,24 @@ bool decompress_file(rzip_control * control) { strcpy(control->outfile, tmpoutfile); } - if (!STDOUT) print_progress("Output filename is: %s\n", control->outfile); + if (!STDOUT) print_progress(, control->outfile); if (unlikely(!strcmp(control->outfile, infilecopy))) { control->flags |= FLAG_TEST_ONLY; // stop and no more decompres or deleting files. - fatal("Output and Input files are the same...Cannot continue\n"); + fatal(); } } if (STDIN) { fd_in = open_tmpinfile(control); read_tmpinmagic(control, fd_in); - if (ENCRYPT) fatal("Cannot decompress encrypted file from STDIN\n"); + if (ENCRYPT) fatal(); expected_size = control->st_size; if (unlikely(!open_tmpinbuf(control))) return false; } else { fd_in = open(infilecopy, O_RDONLY); if (unlikely(fd_in == -1)) { - fatal("Failed to open %s\n", infilecopy); + fatal(, infilecopy); } } control->fd_in = fd_in; @@ -1778,17 +1778,17 @@ bool decompress_file(rzip_control * control) { if (!(TEST_ONLY || STDOUT)) { fd_out = open(control->outfile, O_WRONLY | O_CREAT | O_EXCL, 0666); if (FORCE_REPLACE && (-1 == fd_out) && (EEXIST == errno)) { - if (unlikely(unlink(control->outfile))) fatal("Failed to unlink an existing file: %s\n", control->outfile); + if (unlikely(unlink(control->outfile))) fatal(, control->outfile); fd_out = open(control->outfile, O_WRONLY | O_CREAT | O_EXCL, 0666); } if (unlikely(fd_out == -1)) { /* We must ensure we don't delete a file that already * exists just because we tried to create a new one */ control->flags |= FLAG_KEEP_BROKEN; - fatal("Failed to create %s\n", control->outfile); + fatal(, control->outfile); } fd_hist = open(control->outfile, O_RDONLY); - if (unlikely(fd_hist == -1)) fatal("Failed to open history file %s\n", control->outfile); + if (unlikely(fd_hist == -1)) fatal(, control->outfile); /* Can't copy permissions from STDIN */ if (!STDIN) @@ -1799,9 +1799,9 @@ bool decompress_file(rzip_control * control) { fd_hist = -1; } else { fd_hist = open(control->outfile, O_RDONLY); - if (unlikely(fd_hist == -1)) fatal("Failed to open history file %s\n", control->outfile); + if (unlikely(fd_hist == -1)) fatal(, control->outfile); /* Unlink temporary file as soon as possible */ - if (unlikely(unlink(control->outfile))) fatal("Failed to unlink tmpfile: %s\n", control->outfile); + if (unlikely(unlink(control->outfile))) fatal(, control->outfile); } } @@ -1810,24 +1810,24 @@ bool decompress_file(rzip_control * control) { if (!STDIN) { if (unlikely(!read_magic(control, fd_in, &expected_size))) return false; - if (unlikely(expected_size < 0)) fatal("Invalid expected size %'" PRId64 "\n", expected_size); + if (unlikely(expected_size < 0)) fatal(, expected_size); } if (!STDOUT) { /* Check if there's enough free space on the device chosen to fit the * decompressed or test file. */ - if (unlikely(fstatvfs(fd_out, &fbuf))) fatal("Failed to fstatvfs in decompress_file\n"); + if (unlikely(fstatvfs(fd_out, &fbuf))) fatal(); free_space = (i64)fbuf.f_bsize * (i64)fbuf.f_bavail; if (free_space < expected_size) { if (FORCE_REPLACE && !TEST_ONLY) print_err( - "Warning, inadequate free space detected, but attempting to decompress file due to -f option being " - "used.\n"); + + ); else - fatal("Inadequate free space to %s. Space needed: %'" PRId64 ". Space available: %'" PRId64 - ".\nTry %s and select a larger volume.\n", - TEST_ONLY ? "test file" : "decompress file. Use -f to override", expected_size, free_space, - TEST_ONLY ? "setting `TMP=dirname`" : "using `-O dirname` or `-o [dirname/]filename` options"); + fatal( PRId64 + , + TEST_ONLY ? , expected_size, free_space, + TEST_ONLY ? ); } } control->fd_out = fd_out; @@ -1835,33 +1835,33 @@ bool decompress_file(rzip_control * control) { show_version(control); - if (NO_HASH) print_verbose("Not performing hash check\n"); + if (NO_HASH) print_verbose(); if (HAS_HASH) - print_verbose("%s ", control->hash_label); + print_verbose(, control->hash_label); else - print_verbose("CRC32 "); - print_verbose("being used for integrity testing.\n"); + print_verbose(); + print_verbose(); control->hash_resblock = calloc(*control->hash_len, 1); if (ENCRYPT && !control->salt_pass_len) { // Only get password if needed if (unlikely(!get_hash(control, 0))) return false; - print_maxverbose("Encryption hash loops %'" PRId64 "\n", control->encloops); - if (!INFO) print_verbose("%s Encryption Used\n", control->enc_label); + print_maxverbose(, control->encloops); + if (!INFO) print_verbose(, control->enc_label); } // vailidate file on decompression or test if (STDIN) - print_err("Unable to validate a file from STDIN. To validate, check file directly.\n"); + print_err(); else { - print_progress("Validating file for consistency..."); + print_progress(); if (unlikely((get_fileinfo(control)) == false)) - fatal("File validation failed. Corrupt mrzip archive. Cannot continue\n"); - print_progress("[OK]"); - if (!VERBOSE) print_progress("\n"); // output LF to prevent overwriing decompression output + fatal(); + print_progress(); + if (!VERBOSE) print_progress(); // output LF to prevent overwriing decompression output } show_version(control); // show version here to preserve output formatting - print_progress("Decompressing..."); + print_progress(); if (unlikely(runzip_fd(control, fd_in, fd_out, fd_hist, expected_size) < 0)) { clear_rulist(control); @@ -1877,25 +1877,25 @@ bool decompress_file(rzip_control * control) { } /* if we get here, no fatal_return(( errors during decompression */ - print_progress("\r"); - if (!(STDOUT || TEST_ONLY)) print_progress("Output filename is: %s: ", control->outfile); + print_progress(); + if (!(STDOUT || TEST_ONLY)) print_progress(, control->outfile); if (!expected_size) expected_size = control->st_size; if (!ENCRYPT) - print_progress("[OK] - %'" PRId64 " bytes \n", expected_size); + print_progress(, expected_size); else - print_progress("[OK] \n"); + print_progress(); if (TMP_OUTBUF) close_tmpoutbuf(control); if (fd_out > 0) - if (unlikely(close(fd_hist) || close(fd_out))) fatal("Failed to close files\n"); + if (unlikely(close(fd_hist) || close(fd_out))) fatal(); if (unlikely(!STDIN && !STDOUT && !TEST_ONLY && !preserve_times(control, fd_in))) return false; if (!STDIN) close(fd_in); if (!KEEP_FILES && !STDIN) - if (unlikely(unlink(control->infile))) fatal("Failed to unlink %s\n", infilecopy); + if (unlikely(unlink(control->infile))) fatal(, infilecopy); if (ENCRYPT) release_hashes(control); @@ -1906,11 +1906,11 @@ bool decompress_file(rzip_control * control) { bool initialise_control(rzip_control * control) { time_t now_t, tdiff; - char localeptr[] = "/tmp", *eptr; /* for environment. OR Default to /tmp if none set */ + char localeptr[] = , *eptr; /* for environment. OR Default to /tmp if none set */ size_t len; memset(control, 0, sizeof(rzip_control)); - control->locale = ""; /* empty string for default locale */ + control->locale = ; /* empty string for default locale */ control->msgout = stderr; control->msgerr = stderr; register_outputfile(control, control->msgout); @@ -1929,9 +1929,9 @@ bool initialise_control(rzip_control * control) { /* The first 5 bytes of the salt is the time in seconds. * The next 2 bytes encode how many times to hash the password. * The last 9 bytes are random data, making 16 bytes of salt */ - if (unlikely((now_t = time(NULL)) == ((time_t)-1))) fatal("Failed to call time in main\n"); + if (unlikely((now_t = time(NULL)) == ((time_t)-1))) fatal(); if (unlikely(now_t < T_ZERO)) { - print_output("Warning your time reads before the year 2011, check your system clock\n"); + print_output(); now_t = T_ZERO; } /* Workaround for CPUs no longer keeping up with Moore's law! @@ -1943,15 +1943,15 @@ bool initialise_control(rzip_control * control) { gcry_create_nonce(control->salt + 2, 6); /* Get Temp Dir. Try variations on canonical unix environment variable */ - eptr = getenv("TMPDIR"); - if (!eptr) eptr = getenv("TMP"); - if (!eptr) eptr = getenv("TEMPDIR"); - if (!eptr) eptr = getenv("TEMP"); + eptr = getenv(); + if (!eptr) eptr = getenv(); + if (!eptr) eptr = getenv(); + if (!eptr) eptr = getenv(); if (!eptr) eptr = localeptr; len = strlen(eptr); control->tmpdir = malloc(len + 2); - if (control->tmpdir == NULL) fatal("Failed to allocate for tmpdir\n"); + if (control->tmpdir == NULL) fatal(); strcpy(control->tmpdir, eptr); if (control->tmpdir[len - 1] != '/') { control->tmpdir[len] = '/'; /* need a trailing slash */ @@ -1963,25 +1963,6 @@ bool initialise_control(rzip_control * control) { return true; } -/* - Copyright (C) 2006-2016 Con Kolivas - Copyright (C) 2011 Peter Hyman - Copyright (C) 1998 Andrew Tridgell - Copyright (C) 2022 Kamila Szewczyk - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ #ifndef MRZIP_UTIL_H #define MRZIP_UTIL_H @@ -1992,7 +1973,7 @@ bool initialise_control(rzip_control * control) { #include #include -#include "./mrzip_private.h" +#include void register_infile(rzip_control * control, const char * name, char delete); void register_outfile(rzip_control * control, const char * name, char delete); @@ -2006,9 +1987,6 @@ size_t round_up_page(rzip_control * control, size_t len); bool read_config(rzip_control * control); void lrz_stretch(rzip_control * control); bool lrz_crypt(const rzip_control * control, uchar * buf, i64 len, const uchar * salt, int encrypt); -/* decrypt_header will take a final variable for either decrypt or validate. - * Valdidate will suppress printing message during validation or info - */ bool decrypt_header(rzip_control * control, uchar * head, uchar * c_type, i64 * c_len, i64 * u_len, i64 * last_head, int decompress_type); @@ -2042,7 +2020,7 @@ static inline bool lrz_decrypt(const rzip_control * control, uchar * buf, i64 le static inline void cksem_init(const rzip_control * control, cksem_t * cksem) { int flags, fd, i; - if (pipe(cksem->pipefd) == -1) fatal("Failed pipe errno=%d", errno); + if (pipe(cksem->pipefd) == -1) fatal(, errno); /* Make the pipes FD_CLOEXEC to allow them to close should we call * execv on restart. */ @@ -2050,7 +2028,7 @@ static inline void cksem_init(const rzip_control * control, cksem_t * cksem) { fd = cksem->pipefd[i]; flags = fcntl(fd, F_GETFD, 0); flags |= FD_CLOEXEC; - if (fcntl(fd, F_SETFD, flags) == -1) fatal("Failed to fcntl errno=%d", errno); + if (fcntl(fd, F_SETFD, flags) == -1) fatal(, errno); } } @@ -2059,7 +2037,7 @@ static inline void cksem_post(const rzip_control * control, cksem_t * cksem) { int ret; ret = write(cksem->pipefd[1], &buf, 1); - if (unlikely(ret == 0)) fatal("Failed to write in cksem_post errno=%d", errno); + if (unlikely(ret == 0)) fatal(, errno); } static inline void cksem_wait(const rzip_control * control, cksem_t * cksem) { @@ -2067,20 +2045,20 @@ static inline void cksem_wait(const rzip_control * control, cksem_t * cksem) { int ret; ret = read(cksem->pipefd[0], &buf, 1); - if (unlikely(ret == 0)) fatal("Failed to read in cksem_post errno=%d", errno); + if (unlikely(ret == 0)) fatal(, errno); } #else static inline void cksem_init(const rzip_control * control, cksem_t * cksem) { int ret; - if ((ret = sem_init(cksem, 0, 0))) fatal("Failed to sem_init ret=%d errno=%d", ret, errno); + if ((ret = sem_init(cksem, 0, 0))) fatal(, ret, errno); } static inline void cksem_post(const rzip_control * control, cksem_t * cksem) { - if (unlikely(sem_post(cksem))) fatal("Failed to sem_post errno=%d cksem=0x%p", errno, cksem); + if (unlikely(sem_post(cksem))) fatal(, errno, cksem); } static inline void cksem_wait(const rzip_control * control, cksem_t * cksem) { - if (unlikely(sem_wait(cksem))) fatal("Failed to sem_wait errno=%d cksem=0x%p", errno, cksem); + if (unlikely(sem_wait(cksem))) fatal(, errno, cksem); } #endif @@ -2132,7 +2110,7 @@ void InitAudioDevice(void) ma_result result = ma_context_init(NULL, 0, &ctxConfig, &AUDIO.System.context); if (result != MA_SUCCESS) { - TRACELOG(LOG_WARNING, "AUDIO: Failed to initialize context"); + TRACELOG(LOG_WARNING, ); return; } @@ -2152,7 +2130,7 @@ void InitAudioDevice(void) result = ma_device_init(&AUDIO.System.context, &config, &AUDIO.System.device); if (result != MA_SUCCESS) { - TRACELOG(LOG_WARNING, "AUDIO: Failed to initialize playback device"); + TRACELOG(LOG_WARNING, ); ma_context_uninit(&AUDIO.System.context); return; } @@ -2161,7 +2139,7 @@ void InitAudioDevice(void) // want to look at something a bit smarter later on to keep everything real-time, if that's necessary. if (ma_mutex_init(&AUDIO.System.lock) != MA_SUCCESS) { - TRACELOG(LOG_WARNING, "AUDIO: Failed to create mutex for mixing"); + TRACELOG(LOG_WARNING, ); ma_device_uninit(&AUDIO.System.device); ma_context_uninit(&AUDIO.System.context); return; @@ -2172,7 +2150,7 @@ void InitAudioDevice(void) result = ma_device_start(&AUDIO.System.device); if (result != MA_SUCCESS) { - TRACELOG(LOG_WARNING, "AUDIO: Failed to start playback device"); + TRACELOG(LOG_WARNING, ); ma_device_uninit(&AUDIO.System.device); ma_context_uninit(&AUDIO.System.context); return; @@ -2195,9 +2173,9 @@ void CloseAudioDevice(void) AUDIO.System.pcmBuffer = NULL; AUDIO.System.pcmBufferSize = 0; - TRACELOG(LOG_INFO, "AUDIO: Device closed successfully"); + TRACELOG(LOG_INFO, ); } - else TRACELOG(LOG_WARNING, "AUDIO: Device could not be closed, not currently initialized"); + else TRACELOG(LOG_WARNING, ); } // Check if device has been initialized successfully @@ -2231,7 +2209,7 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam if (audioBuffer == NULL) { - TRACELOG(LOG_WARNING, "AUDIO: Failed to allocate memory for buffer"); + TRACELOG(LOG_WARNING, ); return NULL; } @@ -2245,7 +2223,7 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam if (result != MA_SUCCESS) { - TRACELOG(LOG_WARNING, "AUDIO: Failed to create data conversion pipeline"); + TRACELOG(LOG_WARNING, ); RL_FREE(audioBuffer); return NULL; } @@ -2299,309 +2277,6 @@ bool IsAudioBufferPlaying(AudioBuffer *buffer) return result; } -// Play an audio buffer -// NOTE: Buffer is restarted to the start. -// Use PauseAudioBuffer() and ResumeAudioBuffer() if the playback position should be maintained. -void PlayAudioBuffer(AudioBuffer *buffer) -{ - if (buffer != NULL) - { - buffer->playing = true; - buffer->paused = false; - buffer->frameCursorPos = 0; - } -} - -// Stop an audio buffer -void StopAudioBuffer(AudioBuffer *buffer) -{ - if (buffer != NULL) - { - if (IsAudioBufferPlaying(buffer)) - { - buffer->playing = false; - buffer->paused = false; - buffer->frameCursorPos = 0; - buffer->framesProcessed = 0; - buffer->isSubBufferProcessed[0] = true; - buffer->isSubBufferProcessed[1] = true; - } - } -} - -// Pause an audio buffer -void PauseAudioBuffer(AudioBuffer *buffer) -{ - if (buffer != NULL) buffer->paused = true; -} - -// Resume an audio buffer -void ResumeAudioBuffer(AudioBuffer *buffer) -{ - if (buffer != NULL) buffer->paused = false; -} - -// Set volume for an audio buffer -void SetAudioBufferVolume(AudioBuffer *buffer, float volume) -{ - if (buffer != NULL) buffer->volume = volume; -} - -// Set pitch for an audio buffer -void SetAudioBufferPitch(AudioBuffer *buffer, float pitch) -{ - if ((buffer != NULL) && (pitch > 0.0f)) - { - // Pitching is just an adjustment of the sample rate. - // Note that this changes the duration of the sound: - // - higher pitches will make the sound faster - // - lower pitches make it slower - ma_uint32 outputSampleRate = (ma_uint32)((float)buffer->converter.sampleRateOut/pitch); - ma_data_converter_set_rate(&buffer->converter, buffer->converter.sampleRateIn, outputSampleRate); - - buffer->pitch = pitch; - } -} - -// Set pan for an audio buffer -void SetAudioBufferPan(AudioBuffer *buffer, float pan) -{ - if (pan < 0.0f) pan = 0.0f; - else if (pan > 1.0f) pan = 1.0f; - - if (buffer != NULL) buffer->pan = pan; -} - -// Track audio buffer to linked list next position -void TrackAudioBuffer(AudioBuffer *buffer) -{ - ma_mutex_lock(&AUDIO.System.lock); - { - if (AUDIO.Buffer.first == NULL) AUDIO.Buffer.first = buffer; - else - { - AUDIO.Buffer.last->next = buffer; - buffer->prev = AUDIO.Buffer.last; - } - - AUDIO.Buffer.last = buffer; - } - ma_mutex_unlock(&AUDIO.System.lock); -} - -// Untrack audio buffer from linked list -void UntrackAudioBuffer(AudioBuffer *buffer) -{ - ma_mutex_lock(&AUDIO.System.lock); - { - if (buffer->prev == NULL) AUDIO.Buffer.first = buffer->next; - else buffer->prev->next = buffer->next; - - if (buffer->next == NULL) AUDIO.Buffer.last = buffer->prev; - else buffer->next->prev = buffer->prev; - - buffer->prev = NULL; - buffer->next = NULL; - } - ma_mutex_unlock(&AUDIO.System.lock); -} - -//---------------------------------------------------------------------------------- -// Module Functions Definition - Sounds loading and playing (.WAV) -//---------------------------------------------------------------------------------- - -// Load wave data from file -Wave LoadWave(const char *fileName) -{ - Wave wave = { 0 }; - - // Loading file to memory - int dataSize = 0; - unsigned char *fileData = LoadFileData(fileName, &dataSize); - - // Loading wave from memory data - if (fileData != NULL) wave = LoadWaveFromMemory(GetFileExtension(fileName), fileData, dataSize); - - RL_FREE(fileData); - - return wave; -} - -// Load wave from memory buffer, fileType refers to extension: i.e. ".wav" -// WARNING: File extension must be provided in lower-case -Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize) -{ - Wave wave = { 0 }; - - if (false) { } -#if defined(SUPPORT_FILEFORMAT_WAV) - else if ((strcmp(fileType, ".wav") == 0) || (strcmp(fileType, ".WAV") == 0)) - { - drwav wav = { 0 }; - bool success = drwav_init_memory(&wav, fileData, dataSize, NULL); - - if (success) - { - wave.frameCount = (unsigned int)wav.totalPCMFrameCount; - wave.sampleRate = wav.sampleRate; - wave.sampleSize = 16; - wave.channels = wav.channels; - wave.data = (short *)RL_MALLOC(wave.frameCount*wave.channels*sizeof(short)); - - // NOTE: We are forcing conversion to 16bit sample size on reading - drwav_read_pcm_frames_s16(&wav, wav.totalPCMFrameCount, wave.data); - } - else TRACELOG(LOG_WARNING, "WAVE: Failed to load WAV data"); - - drwav_uninit(&wav); - } -#endif -#if defined(SUPPORT_FILEFORMAT_OGG) - else if ((strcmp(fileType, ".ogg") == 0) || (strcmp(fileType, ".OGG") == 0)) - { - stb_vorbis *oggData = stb_vorbis_open_memory((unsigned char *)fileData, dataSize, NULL, NULL); - - if (oggData != NULL) - { - stb_vorbis_info info = stb_vorbis_get_info(oggData); - - wave.sampleRate = info.sample_rate; - wave.sampleSize = 16; // By default, ogg data is 16 bit per sample (short) - wave.channels = info.channels; - wave.frameCount = (unsigned int)stb_vorbis_stream_length_in_samples(oggData); // NOTE: It returns frames! - wave.data = (short *)RL_MALLOC(wave.frameCount*wave.channels*sizeof(short)); - - // NOTE: Get the number of samples to process (be careful! we ask for number of shorts, not bytes!) - stb_vorbis_get_samples_short_interleaved(oggData, info.channels, (short *)wave.data, wave.frameCount*wave.channels); - stb_vorbis_close(oggData); - } - else TRACELOG(LOG_WARNING, "WAVE: Failed to load OGG data"); - } -#endif -#if defined(SUPPORT_FILEFORMAT_MP3) - else if ((strcmp(fileType, ".mp3") == 0) || (strcmp(fileType, ".MP3") == 0)) - { - drmp3_config config = { 0 }; - unsigned long long int totalFrameCount = 0; - - // NOTE: We are forcing conversion to 32bit float sample size on reading - wave.data = drmp3_open_memory_and_read_pcm_frames_f32(fileData, dataSize, &config, &totalFrameCount, NULL); - wave.sampleSize = 32; - - if (wave.data != NULL) - { - wave.channels = config.channels; - wave.sampleRate = config.sampleRate; - wave.frameCount = (int)totalFrameCount; - } - else TRACELOG(LOG_WARNING, "WAVE: Failed to load MP3 data"); - - } -#endif -#if defined(SUPPORT_FILEFORMAT_QOA) - else if ((strcmp(fileType, ".qoa") == 0) || (strcmp(fileType, ".QOA") == 0)) - { - qoa_desc qoa = { 0 }; - - // NOTE: Returned sample data is always 16 bit? - wave.data = qoa_decode(fileData, dataSize, &qoa); - wave.sampleSize = 16; - - if (wave.data != NULL) - { - wave.channels = qoa.channels; - wave.sampleRate = qoa.samplerate; - wave.frameCount = qoa.samples; - } - else TRACELOG(LOG_WARNING, "WAVE: Failed to load QOA data"); - - } -#endif -#if defined(SUPPORT_FILEFORMAT_FLAC) - else if ((strcmp(fileType, ".flac") == 0) || (strcmp(fileType, ".FLAC") == 0)) - { - unsigned long long int totalFrameCount = 0; - - // NOTE: We are forcing conversion to 16bit sample size on reading - wave.data = drflac_open_memory_and_read_pcm_frames_s16(fileData, dataSize, &wave.channels, &wave.sampleRate, &totalFrameCount, NULL); - wave.sampleSize = 16; - - if (wave.data != NULL) wave.frameCount = (unsigned int)totalFrameCount; - else TRACELOG(LOG_WARNING, "WAVE: Failed to load FLAC data"); - } -#endif - else TRACELOG(LOG_WARNING, "WAVE: Data format not supported"); - - TRACELOG(LOG_INFO, "WAVE: Data loaded successfully (%i Hz, %i bit, %i channels)", wave.sampleRate, wave.sampleSize, wave.channels); - - return wave; -} - -// Checks if wave data is ready -bool IsWaveReady(Wave wave) -{ - return ((wave.data != NULL) && // Validate wave data available - (wave.frameCount > 0) && // Validate frame count - (wave.sampleRate > 0) && // Validate sample rate is supported - (wave.sampleSize > 0) && // Validate sample size is supported - (wave.channels > 0)); // Validate number of channels supported -} - -// Load sound from file -// NOTE: The entire file is loaded to memory to be played (no-streaming) -Sound LoadSound(const char *fileName) -{ - Wave wave = LoadWave(fileName); - - Sound sound = LoadSoundFromWave(wave); - - UnloadWave(wave); // Sound is loaded, we can unload wave - - return sound; -} - -// Load sound from wave data -// NOTE: Wave data must be unallocated manually -Sound LoadSoundFromWave(Wave wave) -{ - Sound sound = { 0 }; - - if (wave.data != NULL) - { - // When using miniaudio we need to do our own mixing. - // To simplify this we need convert the format of each sound to be consistent with - // the format used to open the playback AUDIO.System.device. We can do this two ways: - // - // 1) Convert the whole sound in one go at load time (here). - // 2) Convert the audio data in chunks at mixing time. - // - // First option has been selected, format conversion is done on the loading stage. - // The downside is that it uses more memory if the original sound is u8 or s16. - ma_format formatIn = ((wave.sampleSize == 8)? ma_format_u8 : ((wave.sampleSize == 16)? ma_format_s16 : ma_format_f32)); - ma_uint32 frameCountIn = wave.frameCount; - - ma_uint32 frameCount = (ma_uint32)ma_convert_frames(NULL, 0, AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, NULL, frameCountIn, formatIn, wave.channels, wave.sampleRate); - if (frameCount == 0) TRACELOG(LOG_WARNING, "SOUND: Failed to get frame count for format conversion"); - - AudioBuffer *audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, frameCount, AUDIO_BUFFER_USAGE_STATIC); - if (audioBuffer == NULL) - { - TRACELOG(LOG_WARNING, "SOUND: Failed to create buffer"); - return sound; // early return to avoid dereferencing the audioBuffer null pointer - } - - frameCount = (ma_uint32)ma_convert_frames(audioBuffer->data, frameCount, AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, wave.data, frameCountIn, formatIn, wave.channels, wave.sampleRate); - if (frameCount == 0) TRACELOG(LOG_WARNING, "SOUND: Failed format conversion"); - - sound.frameCount = frameCount; - sound.stream.sampleRate = AUDIO.System.device.sampleRate; - sound.stream.sampleSize = 32; - sound.stream.channels = AUDIO_DEVICE_CHANNELS; - sound.stream.buffer = audioBuffer; - } - - return sound; -} // Clone sound from existing sound data, clone does not own wave data // NOTE: Wave data must be unallocated manually and will be shared across all clones @@ -2614,7 +2289,7 @@ Sound LoadSoundAlias(Sound source) AudioBuffer* audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC); if (audioBuffer == NULL) { - TRACELOG(LOG_WARNING, "SOUND: Failed to create buffer"); + TRACELOG(LOG_WARNING, ); return sound; // early return to avoid dereferencing the audioBuffer null pointer } audioBuffer->sizeInFrames = source.stream.buffer->sizeInFrames; @@ -2646,14 +2321,14 @@ bool IsSoundReady(Sound sound) void UnloadWave(Wave wave) { RL_FREE(wave.data); - //TRACELOG(LOG_INFO, "WAVE: Unloaded wave data from RAM"); + //TRACELOG(LOG_INFO, ); } // Unload sound void UnloadSound(Sound sound) { UnloadAudioBuffer(sound.stream.buffer); - //TRACELOG(LOG_INFO, "SOUND: Unloaded sound data from RAM"); + //TRACELOG(LOG_INFO, ); } void UnloadSoundAlias(Sound alias) @@ -2667,142 +2342,6 @@ void UnloadSoundAlias(Sound alias) } } -// Update sound buffer with new data -void UpdateSound(Sound sound, const void *data, int frameCount) -{ - if (sound.stream.buffer != NULL) - { - StopAudioBuffer(sound.stream.buffer); - - // TODO: May want to lock/unlock this since this data buffer is read at mixing time - memcpy(sound.stream.buffer->data, data, frameCount*ma_get_bytes_per_frame(sound.stream.buffer->converter.formatIn, sound.stream.buffer->converter.channelsIn)); - } -} - -// Export wave data to file -bool ExportWave(Wave wave, const char *fileName) -{ - bool success = false; - - if (false) { } -#if defined(SUPPORT_FILEFORMAT_WAV) - else if (IsFileExtension(fileName, ".wav")) - { - drwav wav = { 0 }; - drwav_data_format format = { 0 }; - format.container = drwav_container_riff; - if (wave.sampleSize == 32) format.format = DR_WAVE_FORMAT_IEEE_FLOAT; - else format.format = DR_WAVE_FORMAT_PCM; - format.channels = wave.channels; - format.sampleRate = wave.sampleRate; - format.bitsPerSample = wave.sampleSize; - - void *fileData = NULL; - size_t fileDataSize = 0; - success = drwav_init_memory_write(&wav, &fileData, &fileDataSize, &format, NULL); - if (success) success = (int)drwav_write_pcm_frames(&wav, wave.frameCount, wave.data); - drwav_result result = drwav_uninit(&wav); - - if (result == DRWAV_SUCCESS) success = SaveFileData(fileName, (unsigned char *)fileData, (unsigned int)fileDataSize); - - drwav_free(fileData, NULL); - } -#endif -#if defined(SUPPORT_FILEFORMAT_QOA) - else if (IsFileExtension(fileName, ".qoa")) - { - if (wave.sampleSize == 16) - { - qoa_desc qoa = { 0 }; - qoa.channels = wave.channels; - qoa.samplerate = wave.sampleRate; - qoa.samples = wave.frameCount; - - int bytesWritten = qoa_write(fileName, wave.data, &qoa); - if (bytesWritten > 0) success = true; - } - else TRACELOG(LOG_WARNING, "AUDIO: Wave data must be 16 bit per sample for QOA format export"); - } -#endif - else if (IsFileExtension(fileName, ".raw")) - { - // Export raw sample data (without header) - // NOTE: It's up to the user to track wave parameters - success = SaveFileData(fileName, wave.data, wave.frameCount*wave.channels*wave.sampleSize/8); - } - - if (success) TRACELOG(LOG_INFO, "FILEIO: [%s] Wave data exported successfully", fileName); - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export wave data", fileName); - - return success; -} - -// Export wave sample data to code (.h) -bool ExportWaveAsCode(Wave wave, const char *fileName) -{ - bool success = false; - -#ifndef TEXT_BYTES_PER_LINE - #define TEXT_BYTES_PER_LINE 20 -#endif - - int waveDataSize = wave.frameCount*wave.channels*wave.sampleSize/8; - - // NOTE: Text data buffer size is estimated considering wave data size in bytes - // and requiring 6 char bytes for every byte: "0x00, " - char *txtData = (char *)RL_CALLOC(waveDataSize*6 + 2000, sizeof(char)); - - int byteCount = 0; - byteCount += sprintf(txtData + byteCount, "\n//////////////////////////////////////////////////////////////////////////////////\n"); - byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// WaveAsCode exporter v1.1 - Wave data exported as an array of bytes //\n"); - byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); - byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); - byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2023 Ramon Santamaria (@raysan5) //\n"); - byteCount += sprintf(txtData + byteCount, "// //\n"); - byteCount += sprintf(txtData + byteCount, "//////////////////////////////////////////////////////////////////////////////////\n\n"); - - // Get file name from path and convert variable name to uppercase - char varFileName[256] = { 0 }; - strcpy(varFileName, GetFileNameWithoutExt(fileName)); - for (int i = 0; varFileName[i] != '\0'; i++) if (varFileName[i] >= 'a' && varFileName[i] <= 'z') { varFileName[i] = varFileName[i] - 32; } - - //Add wave information - byteCount += sprintf(txtData + byteCount, "// Wave data information\n"); - byteCount += sprintf(txtData + byteCount, "#define %s_FRAME_COUNT %u\n", varFileName, wave.frameCount); - byteCount += sprintf(txtData + byteCount, "#define %s_SAMPLE_RATE %u\n", varFileName, wave.sampleRate); - byteCount += sprintf(txtData + byteCount, "#define %s_SAMPLE_SIZE %u\n", varFileName, wave.sampleSize); - byteCount += sprintf(txtData + byteCount, "#define %s_CHANNELS %u\n\n", varFileName, wave.channels); - - // Write wave data as an array of values - // Wave data is exported as byte array for 8/16bit and float array for 32bit float data - // NOTE: Frame data exported is channel-interlaced: frame01[sampleChannel1, sampleChannel2, ...], frame02[], frame03[] - if (wave.sampleSize == 32) - { - byteCount += sprintf(txtData + byteCount, "static float %s_DATA[%i] = {\n", varFileName, waveDataSize/4); - for (int i = 1; i < waveDataSize/4; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.4ff,\n " : "%.4ff, "), ((float *)wave.data)[i - 1]); - byteCount += sprintf(txtData + byteCount, "%.4ff };\n", ((float *)wave.data)[waveDataSize/4 - 1]); - } - else - { - byteCount += sprintf(txtData + byteCount, "static unsigned char %s_DATA[%i] = { ", varFileName, waveDataSize); - for (int i = 1; i < waveDataSize; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n " : "0x%x, "), ((unsigned char *)wave.data)[i - 1]); - byteCount += sprintf(txtData + byteCount, "0x%x };\n", ((unsigned char *)wave.data)[waveDataSize - 1]); - } - - // NOTE: Text data length exported is determined by '\0' (NULL) character - success = SaveFileText(fileName, txtData); - - RL_FREE(txtData); - - if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Wave as code exported successfully", fileName); - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export wave as code", fileName); - - return success; -} - // Play a sound void PlaySound(Sound sound) { @@ -2862,7 +2401,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) if (frameCount == 0) { - TRACELOG(LOG_WARNING, "WAVE: Failed to get frame count for format conversion"); + TRACELOG(LOG_WARNING, ); return; } @@ -2871,7 +2410,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) frameCount = (ma_uint32)ma_convert_frames(data, frameCount, formatOut, channels, sampleRate, wave->data, frameCountIn, formatIn, wave->channels, wave->sampleRate); if (frameCount == 0) { - TRACELOG(LOG_WARNING, "WAVE: Failed format conversion"); + TRACELOG(LOG_WARNING, ); return; } @@ -2884,575 +2423,6 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) wave->data = data; } -// Copy a wave to a new wave -Wave WaveCopy(Wave wave) -{ - Wave newWave = { 0 }; - - newWave.data = RL_MALLOC(wave.frameCount*wave.channels*wave.sampleSize/8); - - if (newWave.data != NULL) - { - // NOTE: Size must be provided in bytes - memcpy(newWave.data, wave.data, wave.frameCount*wave.channels*wave.sampleSize/8); - - newWave.frameCount = wave.frameCount; - newWave.sampleRate = wave.sampleRate; - newWave.sampleSize = wave.sampleSize; - newWave.channels = wave.channels; - } - - return newWave; -} - -// Crop a wave to defined samples range -// NOTE: Security check in case of out-of-range -void WaveCrop(Wave *wave, int initSample, int finalSample) -{ - if ((initSample >= 0) && (initSample < finalSample) && ((unsigned int)finalSample < (wave->frameCount*wave->channels))) - { - int sampleCount = finalSample - initSample; - - void *data = RL_MALLOC(sampleCount*wave->sampleSize/8); - - memcpy(data, (unsigned char *)wave->data + (initSample*wave->channels*wave->sampleSize/8), sampleCount*wave->sampleSize/8); - - RL_FREE(wave->data); - wave->data = data; - } - else TRACELOG(LOG_WARNING, "WAVE: Crop range out of bounds"); -} - -// Load samples data from wave as a floats array -// NOTE 1: Returned sample values are normalized to range [-1..1] -// NOTE 2: Sample data allocated should be freed with UnloadWaveSamples() -float *LoadWaveSamples(Wave wave) -{ - float *samples = (float *)RL_MALLOC(wave.frameCount*wave.channels*sizeof(float)); - - // NOTE: sampleCount is the total number of interlaced samples (including channels) - - for (unsigned int i = 0; i < wave.frameCount*wave.channels; i++) - { - if (wave.sampleSize == 8) samples[i] = (float)(((unsigned char *)wave.data)[i] - 127)/256.0f; - else if (wave.sampleSize == 16) samples[i] = (float)(((short *)wave.data)[i])/32767.0f; - else if (wave.sampleSize == 32) samples[i] = ((float *)wave.data)[i]; - } - - return samples; -} - -// Unload samples data loaded with LoadWaveSamples() -void UnloadWaveSamples(float *samples) -{ - RL_FREE(samples); -} - -//---------------------------------------------------------------------------------- -// Module Functions Definition - Music loading and stream playing -//---------------------------------------------------------------------------------- - -// Load music stream from file -Music LoadMusicStream(const char *fileName) -{ - Music music = { 0 }; - bool musicLoaded = false; - - if (false) { } -#if defined(SUPPORT_FILEFORMAT_WAV) - else if (IsFileExtension(fileName, ".wav")) - { - drwav *ctxWav = RL_CALLOC(1, sizeof(drwav)); - bool success = drwav_init_file(ctxWav, fileName, NULL); - - music.ctxType = MUSIC_AUDIO_WAV; - music.ctxData = ctxWav; - - if (success) - { - int sampleSize = ctxWav->bitsPerSample; - if (ctxWav->bitsPerSample == 24) sampleSize = 16; // Forcing conversion to s16 on UpdateMusicStream() - - music.stream = LoadAudioStream(ctxWav->sampleRate, sampleSize, ctxWav->channels); - music.frameCount = (unsigned int)ctxWav->totalPCMFrameCount; - music.looping = true; // Looping enabled by default - musicLoaded = true; - } - } -#endif -#if defined(SUPPORT_FILEFORMAT_OGG) - else if (IsFileExtension(fileName, ".ogg")) - { - // Open ogg audio stream - music.ctxType = MUSIC_AUDIO_OGG; - music.ctxData = stb_vorbis_open_filename(fileName, NULL, NULL); - - if (music.ctxData != NULL) - { - stb_vorbis_info info = stb_vorbis_get_info((stb_vorbis *)music.ctxData); // Get Ogg file info - - // OGG bit rate defaults to 16 bit, it's enough for compressed format - music.stream = LoadAudioStream(info.sample_rate, 16, info.channels); - - // WARNING: It seems this function returns length in frames, not samples, so we multiply by channels - music.frameCount = (unsigned int)stb_vorbis_stream_length_in_samples((stb_vorbis *)music.ctxData); - music.looping = true; // Looping enabled by default - musicLoaded = true; - } - } -#endif -#if defined(SUPPORT_FILEFORMAT_MP3) - else if (IsFileExtension(fileName, ".mp3")) - { - drmp3 *ctxMp3 = RL_CALLOC(1, sizeof(drmp3)); - int result = drmp3_init_file(ctxMp3, fileName, NULL); - - music.ctxType = MUSIC_AUDIO_MP3; - music.ctxData = ctxMp3; - - if (result > 0) - { - music.stream = LoadAudioStream(ctxMp3->sampleRate, 32, ctxMp3->channels); - music.frameCount = (unsigned int)drmp3_get_pcm_frame_count(ctxMp3); - music.looping = true; // Looping enabled by default - musicLoaded = true; - } - } -#endif -#if defined(SUPPORT_FILEFORMAT_QOA) - else if (IsFileExtension(fileName, ".qoa")) - { - qoaplay_desc *ctxQoa = qoaplay_open(fileName); - music.ctxType = MUSIC_AUDIO_QOA; - music.ctxData = ctxQoa; - - if (ctxQoa->file != NULL) - { - // NOTE: We are loading samples are 32bit float normalized data, so, - // we configure the output audio stream to also use float 32bit - music.stream = LoadAudioStream(ctxQoa->info.samplerate, 32, ctxQoa->info.channels); - music.frameCount = ctxQoa->info.samples; - music.looping = true; // Looping enabled by default - musicLoaded = true; - } - } -#endif -#if defined(SUPPORT_FILEFORMAT_FLAC) - else if (IsFileExtension(fileName, ".flac")) - { - music.ctxType = MUSIC_AUDIO_FLAC; - music.ctxData = drflac_open_file(fileName, NULL); - - if (music.ctxData != NULL) - { - drflac *ctxFlac = (drflac *)music.ctxData; - - music.stream = LoadAudioStream(ctxFlac->sampleRate, ctxFlac->bitsPerSample, ctxFlac->channels); - music.frameCount = (unsigned int)ctxFlac->totalPCMFrameCount; - music.looping = true; // Looping enabled by default - musicLoaded = true; - } - } -#endif -#if defined(SUPPORT_FILEFORMAT_XM) - else if (IsFileExtension(fileName, ".xm")) - { - jar_xm_context_t *ctxXm = NULL; - int result = jar_xm_create_context_from_file(&ctxXm, AUDIO.System.device.sampleRate, fileName); - - music.ctxType = MUSIC_MODULE_XM; - music.ctxData = ctxXm; - - if (result == 0) // XM AUDIO.System.context created successfully - { - jar_xm_set_max_loop_count(ctxXm, 0); // Set infinite number of loops - - unsigned int bits = 32; - if (AUDIO_DEVICE_FORMAT == ma_format_s16) bits = 16; - else if (AUDIO_DEVICE_FORMAT == ma_format_u8) bits = 8; - - // NOTE: Only stereo is supported for XM - music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, bits, AUDIO_DEVICE_CHANNELS); - music.frameCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm); // NOTE: Always 2 channels (stereo) - music.looping = true; // Looping enabled by default - jar_xm_reset(ctxXm); // make sure we start at the beginning of the song - musicLoaded = true; - } - } -#endif -#if defined(SUPPORT_FILEFORMAT_MOD) - else if (IsFileExtension(fileName, ".mod")) - { - jar_mod_context_t *ctxMod = RL_CALLOC(1, sizeof(jar_mod_context_t)); - jar_mod_init(ctxMod); - int result = jar_mod_load_file(ctxMod, fileName); - - music.ctxType = MUSIC_MODULE_MOD; - music.ctxData = ctxMod; - - if (result > 0) - { - // NOTE: Only stereo is supported for MOD - music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, 16, AUDIO_DEVICE_CHANNELS); - music.frameCount = (unsigned int)jar_mod_max_samples(ctxMod); // NOTE: Always 2 channels (stereo) - music.looping = true; // Looping enabled by default - musicLoaded = true; - } - } -#endif - else TRACELOG(LOG_WARNING, "STREAM: [%s] File format not supported", fileName); - - if (!musicLoaded) - { - if (false) { } - #if defined(SUPPORT_FILEFORMAT_WAV) - else if (music.ctxType == MUSIC_AUDIO_WAV) drwav_uninit((drwav *)music.ctxData); - #endif - #if defined(SUPPORT_FILEFORMAT_OGG) - else if (music.ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close((stb_vorbis *)music.ctxData); - #endif - #if defined(SUPPORT_FILEFORMAT_MP3) - else if (music.ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)music.ctxData); RL_FREE(music.ctxData); } - #endif - #if defined(SUPPORT_FILEFORMAT_QOA) - else if (music.ctxType == MUSIC_AUDIO_QOA) qoaplay_close((qoaplay_desc *)music.ctxData); - #endif - #if defined(SUPPORT_FILEFORMAT_FLAC) - else if (music.ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)music.ctxData, NULL); - #endif - #if defined(SUPPORT_FILEFORMAT_XM) - else if (music.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)music.ctxData); - #endif - #if defined(SUPPORT_FILEFORMAT_MOD) - else if (music.ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)music.ctxData); RL_FREE(music.ctxData); } - #endif - - music.ctxData = NULL; - TRACELOG(LOG_WARNING, "FILEIO: [%s] Music file could not be opened", fileName); - } - else - { - // Show some music stream info - TRACELOG(LOG_INFO, "FILEIO: [%s] Music file loaded successfully", fileName); - TRACELOG(LOG_INFO, " > Sample rate: %i Hz", music.stream.sampleRate); - TRACELOG(LOG_INFO, " > Sample size: %i bits", music.stream.sampleSize); - TRACELOG(LOG_INFO, " > Channels: %i (%s)", music.stream.channels, (music.stream.channels == 1)? "Mono" : (music.stream.channels == 2)? "Stereo" : "Multi"); - TRACELOG(LOG_INFO, " > Total frames: %i", music.frameCount); - } - - return music; -} - -// Load music stream from memory buffer, fileType refers to extension: i.e. ".wav" -// WARNING: File extension must be provided in lower-case -Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize) -{ - Music music = { 0 }; - bool musicLoaded = false; - - if (false) { } -#if defined(SUPPORT_FILEFORMAT_WAV) - else if ((strcmp(fileType, ".wav") == 0) || (strcmp(fileType, ".WAV") == 0)) - { - drwav *ctxWav = RL_CALLOC(1, sizeof(drwav)); - - bool success = drwav_init_memory(ctxWav, (const void *)data, dataSize, NULL); - - music.ctxType = MUSIC_AUDIO_WAV; - music.ctxData = ctxWav; - - if (success) - { - int sampleSize = ctxWav->bitsPerSample; - if (ctxWav->bitsPerSample == 24) sampleSize = 16; // Forcing conversion to s16 on UpdateMusicStream() - - music.stream = LoadAudioStream(ctxWav->sampleRate, sampleSize, ctxWav->channels); - music.frameCount = (unsigned int)ctxWav->totalPCMFrameCount; - music.looping = true; // Looping enabled by default - musicLoaded = true; - } - } -#endif -#if defined(SUPPORT_FILEFORMAT_OGG) - else if ((strcmp(fileType, ".ogg") == 0) || (strcmp(fileType, ".OGG") == 0)) - { - // Open ogg audio stream - music.ctxType = MUSIC_AUDIO_OGG; - //music.ctxData = stb_vorbis_open_filename(fileName, NULL, NULL); - music.ctxData = stb_vorbis_open_memory((const unsigned char *)data, dataSize, NULL, NULL); - - if (music.ctxData != NULL) - { - stb_vorbis_info info = stb_vorbis_get_info((stb_vorbis *)music.ctxData); // Get Ogg file info - - // OGG bit rate defaults to 16 bit, it's enough for compressed format - music.stream = LoadAudioStream(info.sample_rate, 16, info.channels); - - // WARNING: It seems this function returns length in frames, not samples, so we multiply by channels - music.frameCount = (unsigned int)stb_vorbis_stream_length_in_samples((stb_vorbis *)music.ctxData); - music.looping = true; // Looping enabled by default - musicLoaded = true; - } - } -#endif -#if defined(SUPPORT_FILEFORMAT_MP3) - else if ((strcmp(fileType, ".mp3") == 0) || (strcmp(fileType, ".MP3") == 0)) - { - drmp3 *ctxMp3 = RL_CALLOC(1, sizeof(drmp3)); - int success = drmp3_init_memory(ctxMp3, (const void*)data, dataSize, NULL); - - music.ctxType = MUSIC_AUDIO_MP3; - music.ctxData = ctxMp3; - - if (success) - { - music.stream = LoadAudioStream(ctxMp3->sampleRate, 32, ctxMp3->channels); - music.frameCount = (unsigned int)drmp3_get_pcm_frame_count(ctxMp3); - music.looping = true; // Looping enabled by default - musicLoaded = true; - } - } -#endif -#if defined(SUPPORT_FILEFORMAT_QOA) - else if ((strcmp(fileType, ".qoa") == 0) || (strcmp(fileType, ".QOA") == 0)) - { - qoaplay_desc *ctxQoa = qoaplay_open_memory(data, dataSize); - music.ctxType = MUSIC_AUDIO_QOA; - music.ctxData = ctxQoa; - - if ((ctxQoa->file_data != NULL) && (ctxQoa->file_data_size != 0)) - { - // NOTE: We are loading samples are 32bit float normalized data, so, - // we configure the output audio stream to also use float 32bit - music.stream = LoadAudioStream(ctxQoa->info.samplerate, 32, ctxQoa->info.channels); - music.frameCount = ctxQoa->info.samples; - music.looping = true; // Looping enabled by default - musicLoaded = true; - } - } -#endif -#if defined(SUPPORT_FILEFORMAT_FLAC) - else if ((strcmp(fileType, ".flac") == 0) || (strcmp(fileType, ".FLAC") == 0)) - { - music.ctxType = MUSIC_AUDIO_FLAC; - music.ctxData = drflac_open_memory((const void*)data, dataSize, NULL); - - if (music.ctxData != NULL) - { - drflac *ctxFlac = (drflac *)music.ctxData; - - music.stream = LoadAudioStream(ctxFlac->sampleRate, ctxFlac->bitsPerSample, ctxFlac->channels); - music.frameCount = (unsigned int)ctxFlac->totalPCMFrameCount; - music.looping = true; // Looping enabled by default - musicLoaded = true; - } - } -#endif -#if defined(SUPPORT_FILEFORMAT_XM) - else if ((strcmp(fileType, ".xm") == 0) || (strcmp(fileType, ".XM") == 0)) - { - jar_xm_context_t *ctxXm = NULL; - int result = jar_xm_create_context_safe(&ctxXm, (const char *)data, dataSize, AUDIO.System.device.sampleRate); - if (result == 0) // XM AUDIO.System.context created successfully - { - music.ctxType = MUSIC_MODULE_XM; - jar_xm_set_max_loop_count(ctxXm, 0); // Set infinite number of loops - - unsigned int bits = 32; - if (AUDIO_DEVICE_FORMAT == ma_format_s16) bits = 16; - else if (AUDIO_DEVICE_FORMAT == ma_format_u8) bits = 8; - - // NOTE: Only stereo is supported for XM - music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, bits, 2); - music.frameCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm); // NOTE: Always 2 channels (stereo) - music.looping = true; // Looping enabled by default - jar_xm_reset(ctxXm); // make sure we start at the beginning of the song - - music.ctxData = ctxXm; - musicLoaded = true; - } - } -#endif -#if defined(SUPPORT_FILEFORMAT_MOD) - else if ((strcmp(fileType, ".mod") == 0) || (strcmp(fileType, ".MOD") == 0)) - { - jar_mod_context_t *ctxMod = (jar_mod_context_t *)RL_MALLOC(sizeof(jar_mod_context_t)); - int result = 0; - - jar_mod_init(ctxMod); - - // Copy data to allocated memory for default UnloadMusicStream - unsigned char *newData = (unsigned char *)RL_MALLOC(dataSize); - int it = dataSize/sizeof(unsigned char); - for (int i = 0; i < it; i++) newData[i] = data[i]; - - // Memory loaded version for jar_mod_load_file() - if (dataSize && (dataSize < 32*1024*1024)) - { - ctxMod->modfilesize = dataSize; - ctxMod->modfile = newData; - if (jar_mod_load(ctxMod, (void *)ctxMod->modfile, dataSize)) result = dataSize; - } - - if (result > 0) - { - music.ctxType = MUSIC_MODULE_MOD; - - // NOTE: Only stereo is supported for MOD - music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, 16, 2); - music.frameCount = (unsigned int)jar_mod_max_samples(ctxMod); // NOTE: Always 2 channels (stereo) - music.looping = true; // Looping enabled by default - musicLoaded = true; - - music.ctxData = ctxMod; - musicLoaded = true; - } - } -#endif - else TRACELOG(LOG_WARNING, "STREAM: Data format not supported"); - - if (!musicLoaded) - { - if (false) { } -#if defined(SUPPORT_FILEFORMAT_WAV) - else if (music.ctxType == MUSIC_AUDIO_WAV) drwav_uninit((drwav *)music.ctxData); -#endif -#if defined(SUPPORT_FILEFORMAT_OGG) - else if (music.ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close((stb_vorbis *)music.ctxData); -#endif -#if defined(SUPPORT_FILEFORMAT_MP3) - else if (music.ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)music.ctxData); RL_FREE(music.ctxData); } -#endif -#if defined(SUPPORT_FILEFORMAT_QOA) - else if (music.ctxType == MUSIC_AUDIO_QOA) qoaplay_close((qoaplay_desc *)music.ctxData); -#endif -#if defined(SUPPORT_FILEFORMAT_FLAC) - else if (music.ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)music.ctxData, NULL); -#endif -#if defined(SUPPORT_FILEFORMAT_XM) - else if (music.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)music.ctxData); -#endif -#if defined(SUPPORT_FILEFORMAT_MOD) - else if (music.ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)music.ctxData); RL_FREE(music.ctxData); } -#endif - - music.ctxData = NULL; - TRACELOG(LOG_WARNING, "FILEIO: Music data could not be loaded"); - } - else - { - // Show some music stream info - TRACELOG(LOG_INFO, "FILEIO: Music data loaded successfully"); - TRACELOG(LOG_INFO, " > Sample rate: %i Hz", music.stream.sampleRate); - TRACELOG(LOG_INFO, " > Sample size: %i bits", music.stream.sampleSize); - TRACELOG(LOG_INFO, " > Channels: %i (%s)", music.stream.channels, (music.stream.channels == 1)? "Mono" : (music.stream.channels == 2)? "Stereo" : "Multi"); - TRACELOG(LOG_INFO, " > Total frames: %i", music.frameCount); - } - - return music; -} - -// Checks if a music stream is ready -bool IsMusicReady(Music music) -{ - return ((music.ctxData != NULL) && // Validate context loaded - (music.frameCount > 0) && // Validate audio frame count - (music.stream.sampleRate > 0) && // Validate sample rate is supported - (music.stream.sampleSize > 0) && // Validate sample size is supported - (music.stream.channels > 0)); // Validate number of channels supported -} - -// Unload music stream -void UnloadMusicStream(Music music) -{ - UnloadAudioStream(music.stream); - - if (music.ctxData != NULL) - { - if (false) { } -#if defined(SUPPORT_FILEFORMAT_WAV) - else if (music.ctxType == MUSIC_AUDIO_WAV) drwav_uninit((drwav *)music.ctxData); -#endif -#if defined(SUPPORT_FILEFORMAT_OGG) - else if (music.ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close((stb_vorbis *)music.ctxData); -#endif -#if defined(SUPPORT_FILEFORMAT_MP3) - else if (music.ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)music.ctxData); RL_FREE(music.ctxData); } -#endif -#if defined(SUPPORT_FILEFORMAT_QOA) - else if (music.ctxType == MUSIC_AUDIO_QOA) qoaplay_close((qoaplay_desc *)music.ctxData); -#endif -#if defined(SUPPORT_FILEFORMAT_FLAC) - else if (music.ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)music.ctxData, NULL); -#endif -#if defined(SUPPORT_FILEFORMAT_XM) - else if (music.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)music.ctxData); -#endif -#if defined(SUPPORT_FILEFORMAT_MOD) - else if (music.ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)music.ctxData); RL_FREE(music.ctxData); } -#endif - } -} - -// Start music playing (open stream) -void PlayMusicStream(Music music) -{ - if (music.stream.buffer != NULL) - { - // For music streams, we need to make sure we maintain the frame cursor position - // This is a hack for this section of code in UpdateMusicStream() - // NOTE: In case window is minimized, music stream is stopped, just make sure to - // play again on window restore: if (IsMusicStreamPlaying(music)) PlayMusicStream(music); - ma_uint32 frameCursorPos = music.stream.buffer->frameCursorPos; - PlayAudioStream(music.stream); // WARNING: This resets the cursor position. - music.stream.buffer->frameCursorPos = frameCursorPos; - } -} - -// Pause music playing -void PauseMusicStream(Music music) -{ - PauseAudioStream(music.stream); -} - -// Resume music playing -void ResumeMusicStream(Music music) -{ - ResumeAudioStream(music.stream); -} - -// Stop music playing (close stream) -void StopMusicStream(Music music) -{ - StopAudioStream(music.stream); - - switch (music.ctxType) - { -#if defined(SUPPORT_FILEFORMAT_WAV) - case MUSIC_AUDIO_WAV: drwav_seek_to_first_pcm_frame((drwav *)music.ctxData); break; -#endif -#if defined(SUPPORT_FILEFORMAT_OGG) - case MUSIC_AUDIO_OGG: stb_vorbis_seek_start((stb_vorbis *)music.ctxData); break; -#endif -#if defined(SUPPORT_FILEFORMAT_MP3) - case MUSIC_AUDIO_MP3: drmp3_seek_to_start_of_stream((drmp3 *)music.ctxData); break; -#endif -#if defined(SUPPORT_FILEFORMAT_QOA) - case MUSIC_AUDIO_QOA: qoaplay_rewind((qoaplay_desc *)music.ctxData); break; -#endif -#if defined(SUPPORT_FILEFORMAT_FLAC) - case MUSIC_AUDIO_FLAC: drflac__seek_to_first_frame((drflac *)music.ctxData); break; -#endif -#if defined(SUPPORT_FILEFORMAT_XM) - case MUSIC_MODULE_XM: jar_xm_reset((jar_xm_context_t *)music.ctxData); break; -#endif -#if defined(SUPPORT_FILEFORMAT_MOD) - case MUSIC_MODULE_MOD: jar_mod_seek_start((jar_mod_context_t *)music.ctxData); break; -#endif - default: break; - } -} - // Seek music to a certain position (in seconds) void SeekMusicStream(Music music, float position) { @@ -3651,40 +2621,6 @@ void UpdateMusicStream(Music music) if (IsMusicStreamPlaying(music)) PlayMusicStream(music); } -// Check if any music is playing -bool IsMusicStreamPlaying(Music music) -{ - return IsAudioStreamPlaying(music.stream); -} - -// Set volume for music -void SetMusicVolume(Music music, float volume) -{ - SetAudioStreamVolume(music.stream, volume); -} - -// Set pitch for music -void SetMusicPitch(Music music, float pitch) -{ - SetAudioBufferPitch(music.stream.buffer, pitch); -} - -// Set pan for a music -void SetMusicPan(Music music, float pan) -{ - SetAudioBufferPan(music.stream.buffer, pan); -} - -// Get music time length (in seconds) -float GetMusicTimeLength(Music music) -{ - float totalSeconds = 0.0f; - - totalSeconds = (float)music.frameCount/music.stream.sampleRate; - - return totalSeconds; -} - // Get current music time played (in seconds) float GetMusicTimePlayed(Music music) { @@ -3742,9 +2678,9 @@ AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, un if (stream.buffer != NULL) { stream.buffer->looping = true; // Always loop for streaming buffers - TRACELOG(LOG_INFO, "STREAM: Initialized successfully (%i Hz, %i bit, %s)", stream.sampleRate, stream.sampleSize, (stream.channels == 1)? "Mono" : "Stereo"); + TRACELOG(LOG_INFO, ); } - else TRACELOG(LOG_WARNING, "STREAM: Failed to load audio buffer, stream could not be created"); + else TRACELOG(LOG_WARNING, ); return stream; } @@ -3763,7 +2699,7 @@ void UnloadAudioStream(AudioStream stream) { UnloadAudioBuffer(stream.buffer); - TRACELOG(LOG_INFO, "STREAM: Unloaded audio stream data from RAM"); + TRACELOG(LOG_INFO, ); } // Update audio stream buffers with data @@ -3812,437 +2748,12 @@ void UpdateAudioStream(AudioStream stream, const void *data, int frameCount) stream.buffer->isSubBufferProcessed[subBufferToUpdate] = false; } - else TRACELOG(LOG_WARNING, "STREAM: Attempting to write too many frames to buffer"); + else TRACELOG(LOG_WARNING, ); } - else TRACELOG(LOG_WARNING, "STREAM: Buffer not available for updating"); + else TRACELOG(LOG_WARNING, ); } } -// Check if any audio stream buffers requires refill -bool IsAudioStreamProcessed(AudioStream stream) -{ - if (stream.buffer == NULL) return false; - - return (stream.buffer->isSubBufferProcessed[0] || stream.buffer->isSubBufferProcessed[1]); -} - -// Play audio stream -void PlayAudioStream(AudioStream stream) -{ - PlayAudioBuffer(stream.buffer); -} - -// Play audio stream -void PauseAudioStream(AudioStream stream) -{ - PauseAudioBuffer(stream.buffer); -} - -// Resume audio stream playing -void ResumeAudioStream(AudioStream stream) -{ - ResumeAudioBuffer(stream.buffer); -} - -// Check if audio stream is playing. -bool IsAudioStreamPlaying(AudioStream stream) -{ - return IsAudioBufferPlaying(stream.buffer); -} - -// Stop audio stream -void StopAudioStream(AudioStream stream) -{ - StopAudioBuffer(stream.buffer); -} - -// Set volume for audio stream (1.0 is max level) -void SetAudioStreamVolume(AudioStream stream, float volume) -{ - SetAudioBufferVolume(stream.buffer, volume); -} - -// Set pitch for audio stream (1.0 is base level) -void SetAudioStreamPitch(AudioStream stream, float pitch) -{ - SetAudioBufferPitch(stream.buffer, pitch); -} - -// Set pan for audio stream -void SetAudioStreamPan(AudioStream stream, float pan) -{ - SetAudioBufferPan(stream.buffer, pan); -} - -// Default size for new audio streams -void SetAudioStreamBufferSizeDefault(int size) -{ - AUDIO.Buffer.defaultSize = size; -} - -// Audio thread callback to request new data -void SetAudioStreamCallback(AudioStream stream, AudioCallback callback) -{ - if (stream.buffer != NULL) stream.buffer->callback = callback; -} - -// Add processor to audio stream. Contrary to buffers, the order of processors is important. -// The new processor must be added at the end. As there aren't supposed to be a lot of processors attached to -// a given stream, we iterate through the list to find the end. That way we don't need a pointer to the last element. -void AttachAudioStreamProcessor(AudioStream stream, AudioCallback process) -{ - ma_mutex_lock(&AUDIO.System.lock); - - rAudioProcessor *processor = (rAudioProcessor *)RL_CALLOC(1, sizeof(rAudioProcessor)); - processor->process = process; - - rAudioProcessor *last = stream.buffer->processor; - - while (last && last->next) - { - last = last->next; - } - if (last) - { - processor->prev = last; - last->next = processor; - } - else stream.buffer->processor = processor; - - ma_mutex_unlock(&AUDIO.System.lock); -} - -// Remove processor from audio stream -void DetachAudioStreamProcessor(AudioStream stream, AudioCallback process) -{ - ma_mutex_lock(&AUDIO.System.lock); - - rAudioProcessor *processor = stream.buffer->processor; - - while (processor) - { - rAudioProcessor *next = processor->next; - rAudioProcessor *prev = processor->prev; - - if (processor->process == process) - { - if (stream.buffer->processor == processor) stream.buffer->processor = next; - if (prev) prev->next = next; - if (next) next->prev = prev; - - RL_FREE(processor); - } - - processor = next; - } - - ma_mutex_unlock(&AUDIO.System.lock); -} - -// Add processor to audio pipeline. Order of processors is important -// Works the same way as {Attach,Detach}AudioStreamProcessor() functions, except -// these two work on the already mixed output just before sending it to the sound hardware -void AttachAudioMixedProcessor(AudioCallback process) -{ - ma_mutex_lock(&AUDIO.System.lock); - - rAudioProcessor *processor = (rAudioProcessor *)RL_CALLOC(1, sizeof(rAudioProcessor)); - processor->process = process; - - rAudioProcessor *last = AUDIO.mixedProcessor; - - while (last && last->next) - { - last = last->next; - } - if (last) - { - processor->prev = last; - last->next = processor; - } - else AUDIO.mixedProcessor = processor; - - ma_mutex_unlock(&AUDIO.System.lock); -} - -// Remove processor from audio pipeline -void DetachAudioMixedProcessor(AudioCallback process) -{ - ma_mutex_lock(&AUDIO.System.lock); - - rAudioProcessor *processor = AUDIO.mixedProcessor; - - while (processor) - { - rAudioProcessor *next = processor->next; - rAudioProcessor *prev = processor->prev; - - if (processor->process == process) - { - if (AUDIO.mixedProcessor == processor) AUDIO.mixedProcessor = next; - if (prev) prev->next = next; - if (next) next->prev = prev; - - RL_FREE(processor); - } - - processor = next; - } - - ma_mutex_unlock(&AUDIO.System.lock); -} - - -//---------------------------------------------------------------------------------- -// Module specific Functions Definition -//---------------------------------------------------------------------------------- - -// Log callback function -static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage) -{ - TRACELOG(LOG_WARNING, "miniaudio: %s", pMessage); // All log messages from miniaudio are errors -} - -// Reads audio data from an AudioBuffer object in internal format. -static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount) -{ - // Using audio buffer callback - if (audioBuffer->callback) - { - audioBuffer->callback(framesOut, frameCount); - audioBuffer->framesProcessed += frameCount; - - return frameCount; - } - - ma_uint32 subBufferSizeInFrames = (audioBuffer->sizeInFrames > 1)? audioBuffer->sizeInFrames/2 : audioBuffer->sizeInFrames; - ma_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames; - - if (currentSubBufferIndex > 1) return 0; - - // Another thread can update the processed state of buffers, so - // we just take a copy here to try and avoid potential synchronization problems - bool isSubBufferProcessed[2] = { 0 }; - isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0]; - isSubBufferProcessed[1] = audioBuffer->isSubBufferProcessed[1]; - - ma_uint32 frameSizeInBytes = ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn); - - // Fill out every frame until we find a buffer that's marked as processed. Then fill the remainder with 0 - ma_uint32 framesRead = 0; - while (1) - { - // We break from this loop differently depending on the buffer's usage - // - For static buffers, we simply fill as much data as we can - // - For streaming buffers we only fill half of the buffer that are processed - // Unprocessed halves must keep their audio data in-tact - if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC) - { - if (framesRead >= frameCount) break; - } - else - { - if (isSubBufferProcessed[currentSubBufferIndex]) break; - } - - ma_uint32 totalFramesRemaining = (frameCount - framesRead); - if (totalFramesRemaining == 0) break; - - ma_uint32 framesRemainingInOutputBuffer; - if (audioBuffer->usage == AUDIO_BUFFER_USAGE_STATIC) - { - framesRemainingInOutputBuffer = audioBuffer->sizeInFrames - audioBuffer->frameCursorPos; - } - else - { - ma_uint32 firstFrameIndexOfThisSubBuffer = subBufferSizeInFrames*currentSubBufferIndex; - framesRemainingInOutputBuffer = subBufferSizeInFrames - (audioBuffer->frameCursorPos - firstFrameIndexOfThisSubBuffer); - } - - ma_uint32 framesToRead = totalFramesRemaining; - if (framesToRead > framesRemainingInOutputBuffer) framesToRead = framesRemainingInOutputBuffer; - - memcpy((unsigned char *)framesOut + (framesRead*frameSizeInBytes), audioBuffer->data + (audioBuffer->frameCursorPos*frameSizeInBytes), framesToRead*frameSizeInBytes); - audioBuffer->frameCursorPos = (audioBuffer->frameCursorPos + framesToRead)%audioBuffer->sizeInFrames; - framesRead += framesToRead; - - // If we've read to the end of the buffer, mark it as processed - if (framesToRead == framesRemainingInOutputBuffer) - { - audioBuffer->isSubBufferProcessed[currentSubBufferIndex] = true; - isSubBufferProcessed[currentSubBufferIndex] = true; - - currentSubBufferIndex = (currentSubBufferIndex + 1)%2; - - // We need to break from this loop if we're not looping - if (!audioBuffer->looping) - { - StopAudioBuffer(audioBuffer); - break; - } - } - } - - // Zero-fill excess - ma_uint32 totalFramesRemaining = (frameCount - framesRead); - if (totalFramesRemaining > 0) - { - memset((unsigned char *)framesOut + (framesRead*frameSizeInBytes), 0, totalFramesRemaining*frameSizeInBytes); - - // For static buffers we can fill the remaining frames with silence for safety, but we don't want - // to report those frames as "read". The reason for this is that the caller uses the return value - // to know whether a non-looping sound has finished playback. - if (audioBuffer->usage != AUDIO_BUFFER_USAGE_STATIC) framesRead += totalFramesRemaining; - } - - return framesRead; -} - -// Reads audio data from an AudioBuffer object in device format. Returned data will be in a format appropriate for mixing. -static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, float *framesOut, ma_uint32 frameCount) -{ - // What's going on here is that we're continuously converting data from the AudioBuffer's internal format to the mixing format, which - // should be defined by the output format of the data converter. We do this until frameCount frames have been output. The important - // detail to remember here is that we never, ever attempt to read more input data than is required for the specified number of output - // frames. This can be achieved with ma_data_converter_get_required_input_frame_count(). - ma_uint8 inputBuffer[4096] = { 0 }; - ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn); - - ma_uint32 totalOutputFramesProcessed = 0; - while (totalOutputFramesProcessed < frameCount) - { - ma_uint64 outputFramesToProcessThisIteration = frameCount - totalOutputFramesProcessed; - ma_uint64 inputFramesToProcessThisIteration = 0; - - (void)ma_data_converter_get_required_input_frame_count(&audioBuffer->converter, outputFramesToProcessThisIteration, &inputFramesToProcessThisIteration); - if (inputFramesToProcessThisIteration > inputBufferFrameCap) - { - inputFramesToProcessThisIteration = inputBufferFrameCap; - } - - float *runningFramesOut = framesOut + (totalOutputFramesProcessed*audioBuffer->converter.channelsOut); - - /* At this point we can convert the data to our mixing format. */ - ma_uint64 inputFramesProcessedThisIteration = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, (ma_uint32)inputFramesToProcessThisIteration); /* Safe cast. */ - ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration; - ma_data_converter_process_pcm_frames(&audioBuffer->converter, inputBuffer, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration); - - totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; /* Safe cast. */ - - if (inputFramesProcessedThisIteration < inputFramesToProcessThisIteration) - { - break; /* Ran out of input data. */ - } - - /* This should never be hit, but will add it here for safety. Ensures we get out of the loop when no input nor output frames are processed. */ - if (inputFramesProcessedThisIteration == 0 && outputFramesProcessedThisIteration == 0) - { - break; - } - } - - return totalOutputFramesProcessed; -} - -// Sending audio data to device callback function -// This function will be called when miniaudio needs more data -// NOTE: All the mixing takes place here -static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const void *pFramesInput, ma_uint32 frameCount) -{ - (void)pDevice; - - // Mixing is basically just an accumulation, we need to initialize the output buffer to 0 - memset(pFramesOut, 0, frameCount*pDevice->playback.channels*ma_get_bytes_per_sample(pDevice->playback.format)); - - // Using a mutex here for thread-safety which makes things not real-time - // This is unlikely to be necessary for this project, but may want to consider how you might want to avoid this - ma_mutex_lock(&AUDIO.System.lock); - { - for (AudioBuffer *audioBuffer = AUDIO.Buffer.first; audioBuffer != NULL; audioBuffer = audioBuffer->next) - { - // Ignore stopped or paused sounds - if (!audioBuffer->playing || audioBuffer->paused) continue; - - ma_uint32 framesRead = 0; - - while (1) - { - if (framesRead >= frameCount) break; - - // Just read as much data as we can from the stream - ma_uint32 framesToRead = (frameCount - framesRead); - - while (framesToRead > 0) - { - float tempBuffer[1024] = { 0 }; // Frames for stereo - - ma_uint32 framesToReadRightNow = framesToRead; - if (framesToReadRightNow > sizeof(tempBuffer)/sizeof(tempBuffer[0])/AUDIO_DEVICE_CHANNELS) - { - framesToReadRightNow = sizeof(tempBuffer)/sizeof(tempBuffer[0])/AUDIO_DEVICE_CHANNELS; - } - - ma_uint32 framesJustRead = ReadAudioBufferFramesInMixingFormat(audioBuffer, tempBuffer, framesToReadRightNow); - if (framesJustRead > 0) - { - float *framesOut = (float *)pFramesOut + (framesRead*AUDIO.System.device.playback.channels); - float *framesIn = tempBuffer; - - // Apply processors chain if defined - rAudioProcessor *processor = audioBuffer->processor; - while (processor) - { - processor->process(framesIn, framesJustRead); - processor = processor->next; - } - - MixAudioFrames(framesOut, framesIn, framesJustRead, audioBuffer); - - framesToRead -= framesJustRead; - framesRead += framesJustRead; - } - - if (!audioBuffer->playing) - { - framesRead = frameCount; - break; - } - - // If we weren't able to read all the frames we requested, break - if (framesJustRead < framesToReadRightNow) - { - if (!audioBuffer->looping) - { - StopAudioBuffer(audioBuffer); - break; - } - else - { - // Should never get here, but just for safety, - // move the cursor position back to the start and continue the loop - audioBuffer->frameCursorPos = 0; - continue; - } - } - } - - // If for some reason we weren't able to read every frame we'll need to break from the loop - // Not doing this could theoretically put us into an infinite loop - if (framesToRead > 0) break; - } - } - } - - rAudioProcessor *processor = AUDIO.mixedProcessor; - while (processor) - { - processor->process(pFramesOut, frameCount); - processor = processor->next; - } - - ma_mutex_unlock(&AUDIO.System.lock); -} - // Main mixing function, pretty simple in this project, just an accumulation // NOTE: framesOut is both an input and an output, it is initially filled with zeros outside of this function static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, AudioBuffer *buffer) @@ -4302,504 +2813,6 @@ static bool IsFileExtension(const char *fileName, const char *ext) return result; } -// Get pointer to extension for a filename string (includes the dot: .png) -static const char *GetFileExtension(const char *fileName) -{ - const char *dot = strrchr(fileName, '.'); - - if (!dot || dot == fileName) return NULL; - - return dot; -} - -// Load data from file into a buffer -static unsigned char *LoadFileData(const char *fileName, int *dataSize) -{ - unsigned char *data = NULL; - *dataSize = 0; - - if (fileName != NULL) - { - FILE *file = fopen(fileName, "rb"); - - if (file != NULL) - { - // WARNING: On binary streams SEEK_END could not be found, - // using fseek() and ftell() could not work in some (rare) cases - fseek(file, 0, SEEK_END); - int size = ftell(file); - fseek(file, 0, SEEK_SET); - - if (size > 0) - { - data = (unsigned char *)RL_MALLOC(size*sizeof(unsigned char)); - - // NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, size elements] - unsigned int count = (unsigned int)fread(data, sizeof(unsigned char), size, file); - *dataSize = count; - - if (count != size) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially loaded", fileName); - else TRACELOG(LOG_INFO, "FILEIO: [%s] File loaded successfully", fileName); - } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read file", fileName); - - fclose(file); - } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName); - } - else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); - - return data; -} - -// Save data to file from buffer -static bool SaveFileData(const char *fileName, void *data, int dataSize) -{ - if (fileName != NULL) - { - FILE *file = fopen(fileName, "wb"); - - if (file != NULL) - { - unsigned int count = (unsigned int)fwrite(data, sizeof(unsigned char), dataSize, file); - - if (count == 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write file", fileName); - else if (count != dataSize) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially written", fileName); - else TRACELOG(LOG_INFO, "FILEIO: [%s] File saved successfully", fileName); - - fclose(file); - } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName); - } - else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); -} - -// Save text data to file (write), string must be '\0' terminated -static bool SaveFileText(const char *fileName, char *text) -{ - if (fileName != NULL) - { - FILE *file = fopen(fileName, "wt"); - - if (file != NULL) - { - int count = fprintf(file, "%s", text); - - if (count == 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write text file", fileName); - else TRACELOG(LOG_INFO, "FILEIO: [%s] Text file saved successfully", fileName); - - fclose(file); - } - else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName); - } - else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid"); -} -#endif - -#undef AudioBuffer - -#endif // SUPPORT_MODULE_RAUDIO - -#include -#include -#include -#include -#include -#include - -#include "futex.h" -#include "../locking/rtmutex_common.h" - -/* - * The base of the bucket array and its size are always used together - * (after initialization only in futex_hash()), so ensure that they - * reside in the same cacheline. - */ -static struct { - struct futex_hash_bucket *queues; - unsigned long hashsize; -} __futex_data __read_mostly __aligned(2*sizeof(long)); -#define futex_queues (__futex_data.queues) -#define futex_hashsize (__futex_data.hashsize) - - -/* - * Fault injections for futexes. - */ -#ifdef CONFIG_FAIL_FUTEX - -static struct { - struct fault_attr attr; - - bool ignore_private; -} fail_futex = { - .attr = FAULT_ATTR_INITIALIZER, - .ignore_private = false, -}; - -static int __init setup_fail_futex(char *str) -{ - return setup_fault_attr(&fail_futex.attr, str); -} -__setup("fail_futex=", setup_fail_futex); - -bool should_fail_futex(bool fshared) -{ - if (fail_futex.ignore_private && !fshared) - return false; - - return should_fail(&fail_futex.attr, 1); -} - -#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS - -static int __init fail_futex_debugfs(void) -{ - umode_t mode = S_IFREG | S_IRUSR | S_IWUSR; - struct dentry *dir; - - dir = fault_create_debugfs_attr("fail_futex", NULL, - &fail_futex.attr); - if (IS_ERR(dir)) - return PTR_ERR(dir); - - debugfs_create_bool("ignore-private", mode, dir, - &fail_futex.ignore_private); - return 0; -} - -late_initcall(fail_futex_debugfs); - -#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */ - -#endif /* CONFIG_FAIL_FUTEX */ - -/** - * futex_hash - Return the hash bucket in the global hash - * @key: Pointer to the futex key for which the hash is calculated - * - * We hash on the keys returned from get_futex_key (see below) and return the - * corresponding hash bucket in the global hash. - */ -struct futex_hash_bucket *futex_hash(union futex_key *key) -{ - u32 hash = jhash2((u32 *)key, offsetof(typeof(*key), both.offset) / 4, - key->both.offset); - - return &futex_queues[hash & (futex_hashsize - 1)]; -} - - -/** - * futex_setup_timer - set up the sleeping hrtimer. - * @time: ptr to the given timeout value - * @timeout: the hrtimer_sleeper structure to be set up - * @flags: futex flags - * @range_ns: optional range in ns - * - * Return: Initialized hrtimer_sleeper structure or NULL if no timeout - * value given - */ -struct hrtimer_sleeper * -futex_setup_timer(ktime_t *time, struct hrtimer_sleeper *timeout, - int flags, u64 range_ns) -{ - if (!time) - return NULL; - - hrtimer_init_sleeper_on_stack(timeout, (flags & FLAGS_CLOCKRT) ? - CLOCK_REALTIME : CLOCK_MONOTONIC, - HRTIMER_MODE_ABS); - /* - * If range_ns is 0, calling hrtimer_set_expires_range_ns() is - * effectively the same as calling hrtimer_set_expires(). - */ - hrtimer_set_expires_range_ns(&timeout->timer, *time, range_ns); - - return timeout; -} - -/* - * Generate a machine wide unique identifier for this inode. - * - * This relies on u64 not wrapping in the life-time of the machine; which with - * 1ns resolution means almost 585 years. - * - * This further relies on the fact that a well formed program will not unmap - * the file while it has a (shared) futex waiting on it. This mapping will have - * a file reference which pins the mount and inode. - * - * If for some reason an inode gets evicted and read back in again, it will get - * a new sequence number and will _NOT_ match, even though it is the exact same - * file. - * - * It is important that futex_match() will never have a false-positive, esp. - * for PI futexes that can mess up the state. The above argues that false-negatives - * are only possible for malformed programs. - */ -static u64 get_inode_sequence_number(struct inode *inode) -{ - static atomic64_t i_seq; - u64 old; - - /* Does the inode already have a sequence number? */ - old = atomic64_read(&inode->i_sequence); - if (likely(old)) - return old; - - for (;;) { - u64 new = atomic64_add_return(1, &i_seq); - if (WARN_ON_ONCE(!new)) - continue; - - old = atomic64_cmpxchg_relaxed(&inode->i_sequence, 0, new); - if (old) - return old; - return new; - } -} - -/** - * get_futex_key() - Get parameters which are the keys for a futex - * @uaddr: virtual address of the futex - * @flags: FLAGS_* - * @key: address where result is stored. - * @rw: mapping needs to be read/write (values: FUTEX_READ, - * FUTEX_WRITE) - * - * Return: a negative error code or 0 - * - * The key words are stored in @key on success. - * - * For shared mappings (when @fshared), the key is: - * - * ( inode->i_sequence, page->index, offset_within_page ) - * - * [ also see get_inode_sequence_number() ] - * - * For private mappings (or when !@fshared), the key is: - * - * ( current->mm, address, 0 ) - * - * This allows (cross process, where applicable) identification of the futex - * without keeping the page pinned for the duration of the FUTEX_WAIT. - * - * lock_page() might sleep, the caller should not hold a spinlock. - */ -int get_futex_key(u32 __user *uaddr, unsigned int flags, union futex_key *key, - enum futex_access rw) -{ - unsigned long address = (unsigned long)uaddr; - struct mm_struct *mm = current->mm; - struct page *page; - struct folio *folio; - struct address_space *mapping; - int err, ro = 0; - bool fshared; - - fshared = flags & FLAGS_SHARED; - - /* - * The futex address must be "naturally" aligned. - */ - key->both.offset = address % PAGE_SIZE; - if (unlikely((address % sizeof(u32)) != 0)) - return -EINVAL; - address -= key->both.offset; - - if (unlikely(!access_ok(uaddr, sizeof(u32)))) - return -EFAULT; - - if (unlikely(should_fail_futex(fshared))) - return -EFAULT; - - /* - * PROCESS_PRIVATE futexes are fast. - * As the mm cannot disappear under us and the 'key' only needs - * virtual address, we dont even have to find the underlying vma. - * Note : We do have to check 'uaddr' is a valid user address, - * but access_ok() should be faster than find_vma() - */ - if (!fshared) { - /* - * On no-MMU, shared futexes are treated as private, therefore - * we must not include the current process in the key. Since - * there is only one address space, the address is a unique key - * on its own. - */ - if (IS_ENABLED(CONFIG_MMU)) - key->private.mm = mm; - else - key->private.mm = NULL; - - key->private.address = address; - return 0; - } - -again: - /* Ignore any VERIFY_READ mapping (futex common case) */ - if (unlikely(should_fail_futex(true))) - return -EFAULT; - - err = get_user_pages_fast(address, 1, FOLL_WRITE, &page); - /* - * If write access is not required (eg. FUTEX_WAIT), try - * and get read-only access. - */ - if (err == -EFAULT && rw == FUTEX_READ) { - err = get_user_pages_fast(address, 1, 0, &page); - ro = 1; - } - if (err < 0) - return err; - else - err = 0; - - /* - * The treatment of mapping from this point on is critical. The folio - * lock protects many things but in this context the folio lock - * stabilizes mapping, prevents inode freeing in the shared - * file-backed region case and guards against movement to swap cache. - * - * Strictly speaking the folio lock is not needed in all cases being - * considered here and folio lock forces unnecessarily serialization. - * From this point on, mapping will be re-verified if necessary and - * folio lock will be acquired only if it is unavoidable - * - * Mapping checks require the folio so it is looked up now. For - * anonymous pages, it does not matter if the folio is split - * in the future as the key is based on the address. For - * filesystem-backed pages, the precise page is required as the - * index of the page determines the key. - */ - folio = page_folio(page); - mapping = READ_ONCE(folio->mapping); - - /* - * If folio->mapping is NULL, then it cannot be an anonymous - * page; but it might be the ZERO_PAGE or in the gate area or - * in a special mapping (all cases which we are happy to fail); - * or it may have been a good file page when get_user_pages_fast - * found it, but truncated or holepunched or subjected to - * invalidate_complete_page2 before we got the folio lock (also - * cases which we are happy to fail). And we hold a reference, - * so refcount care in invalidate_inode_page's remove_mapping - * prevents drop_caches from setting mapping to NULL beneath us. - * - * The case we do have to guard against is when memory pressure made - * shmem_writepage move it from filecache to swapcache beneath us: - * an unlikely race, but we do need to retry for folio->mapping. - */ - if (unlikely(!mapping)) { - int shmem_swizzled; - - /* - * Folio lock is required to identify which special case above - * applies. If this is really a shmem page then the folio lock - * will prevent unexpected transitions. - */ - folio_lock(folio); - shmem_swizzled = folio_test_swapcache(folio) || folio->mapping; - folio_unlock(folio); - folio_put(folio); - - if (shmem_swizzled) - goto again; - - return -EFAULT; - } - - /* - * Private mappings are handled in a simple way. - * - * If the futex key is stored in anonymous memory, then the associated - * object is the mm which is implicitly pinned by the calling process. - * - * NOTE: When userspace waits on a MAP_SHARED mapping, even if - * it's a read-only handle, it's expected that futexes attach to - * the object not the particular process. - */ - if (folio_test_anon(folio)) { - /* - * A RO anonymous page will never change and thus doesn't make - * sense for futex operations. - */ - if (unlikely(should_fail_futex(true)) || ro) { - err = -EFAULT; - goto out; - } - - key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */ - key->private.mm = mm; - key->private.address = address; - - } else { - struct inode *inode; - - /* - * The associated futex object in this case is the inode and - * the folio->mapping must be traversed. Ordinarily this should - * be stabilised under folio lock but it's not strictly - * necessary in this case as we just want to pin the inode, not - * update i_pages or anything like that. - * - * The RCU read lock is taken as the inode is finally freed - * under RCU. If the mapping still matches expectations then the - * mapping->host can be safely accessed as being a valid inode. - */ - rcu_read_lock(); - - if (READ_ONCE(folio->mapping) != mapping) { - rcu_read_unlock(); - folio_put(folio); - - goto again; - } - - inode = READ_ONCE(mapping->host); - if (!inode) { - rcu_read_unlock(); - folio_put(folio); - - goto again; - } - - key->both.offset |= FUT_OFF_INODE; /* inode-based key */ - key->shared.i_seq = get_inode_sequence_number(inode); - key->shared.pgoff = folio->index + folio_page_idx(folio, page); - rcu_read_unlock(); - } - -out: - folio_put(folio); - return err; -} - -/** - * fault_in_user_writeable() - Fault in user address and verify RW access - * @uaddr: pointer to faulting user space address - * - * Slow path to fixup the fault we just took in the atomic write - * access to @uaddr. - * - * We have no generic implementation of a non-destructive write to the - * user address. We know that we faulted in the atomic pagefault - * disabled section so we can as well avoid the #PF overhead by - * calling get_user_pages() right away. - */ -int fault_in_user_writeable(u32 __user *uaddr) -{ - struct mm_struct *mm = current->mm; - int ret; - - mmap_read_lock(mm); - ret = fixup_user_fault(mm, (unsigned long)uaddr, - FAULT_FLAG_WRITE, NULL); - mmap_read_unlock(mm); - - return ret < 0 ? ret : 0; -} - /** * futex_top_waiter() - Return the highest priority waiter on a futex * @hb: the hash bucket the futex_q's reside in @@ -4921,36 +2934,6 @@ void futex_q_unlock(struct futex_hash_bucket *hb) futex_hb_waiters_dec(hb); } -void __futex_queue(struct futex_q *q, struct futex_hash_bucket *hb) -{ - int prio; - - /* - * The priority used to register this element is - * - either the real thread-priority for the real-time threads - * (i.e. threads with a priority lower than MAX_RT_PRIO) - * - or MAX_RT_PRIO for non-RT threads. - * Thus, all RT-threads are woken first in priority order, and - * the others are woken last, in FIFO order. - */ - prio = min(current->normal_prio, MAX_RT_PRIO); - - plist_node_init(&q->list, prio); - plist_add(&q->list, &hb->chain); - q->task = current; -} - -/** - * futex_unqueue() - Remove the futex_q from its futex_hash_bucket - * @q: The futex_q to unqueue - * - * The q->lock_ptr must not be held by the caller. A call to futex_unqueue() must - * be paired with exactly one earlier call to futex_queue(). - * - * Return: - * - 1 - if the futex_q was still queued (and we removed unqueued it); - * - 0 - if the futex_q was already removed by the waking thread - */ int futex_unqueue(struct futex_q *q) { spinlock_t *lock_ptr; @@ -5011,208 +2994,6 @@ void futex_unqueue_pi(struct futex_q *q) #define HANDLE_DEATH_PENDING true #define HANDLE_DEATH_LIST false -/* - * Process a futex-list entry, check whether it's owned by the - * dying task, and do notification if so: - */ -static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, - bool pi, bool pending_op) -{ - u32 uval, nval, mval; - pid_t owner; - int err; - - /* Futex address must be 32bit aligned */ - if ((((unsigned long)uaddr) % sizeof(*uaddr)) != 0) - return -1; - -retry: - if (get_user(uval, uaddr)) - return -1; - - /* - * Special case for regular (non PI) futexes. The unlock path in - * user space has two race scenarios: - * - * 1. The unlock path releases the user space futex value and - * before it can execute the futex() syscall to wake up - * waiters it is killed. - * - * 2. A woken up waiter is killed before it can acquire the - * futex in user space. - * - * In the second case, the wake up notification could be generated - * by the unlock path in user space after setting the futex value - * to zero or by the kernel after setting the OWNER_DIED bit below. - * - * In both cases the TID validation below prevents a wakeup of - * potential waiters which can cause these waiters to block - * forever. - * - * In both cases the following conditions are met: - * - * 1) task->robust_list->list_op_pending != NULL - * @pending_op == true - * 2) The owner part of user space futex value == 0 - * 3) Regular futex: @pi == false - * - * If these conditions are met, it is safe to attempt waking up a - * potential waiter without touching the user space futex value and - * trying to set the OWNER_DIED bit. If the futex value is zero, - * the rest of the user space mutex state is consistent, so a woken - * waiter will just take over the uncontended futex. Setting the - * OWNER_DIED bit would create inconsistent state and malfunction - * of the user space owner died handling. Otherwise, the OWNER_DIED - * bit is already set, and the woken waiter is expected to deal with - * this. - */ - owner = uval & FUTEX_TID_MASK; - - if (pending_op && !pi && !owner) { - futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY); - return 0; - } - - if (owner != task_pid_vnr(curr)) - return 0; - - /* - * Ok, this dying thread is truly holding a futex - * of interest. Set the OWNER_DIED bit atomically - * via cmpxchg, and if the value had FUTEX_WAITERS - * set, wake up a waiter (if any). (We have to do a - * futex_wake() even if OWNER_DIED is already set - - * to handle the rare but possible case of recursive - * thread-death.) The rest of the cleanup is done in - * userspace. - */ - mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED; - - /* - * We are not holding a lock here, but we want to have - * the pagefault_disable/enable() protection because - * we want to handle the fault gracefully. If the - * access fails we try to fault in the futex with R/W - * verification via get_user_pages. get_user() above - * does not guarantee R/W access. If that fails we - * give up and leave the futex locked. - */ - if ((err = futex_cmpxchg_value_locked(&nval, uaddr, uval, mval))) { - switch (err) { - case -EFAULT: - if (fault_in_user_writeable(uaddr)) - return -1; - goto retry; - - case -EAGAIN: - cond_resched(); - goto retry; - - default: - WARN_ON_ONCE(1); - return err; - } - } - - if (nval != uval) - goto retry; - - /* - * Wake robust non-PI futexes here. The wakeup of - * PI futexes happens in exit_pi_state(): - */ - if (!pi && (uval & FUTEX_WAITERS)) - futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY); - - return 0; -} - -/* - * Fetch a robust-list pointer. Bit 0 signals PI futexes: - */ -static inline int fetch_robust_entry(struct robust_list __user **entry, - struct robust_list __user * __user *head, - unsigned int *pi) -{ - unsigned long uentry; - - if (get_user(uentry, (unsigned long __user *)head)) - return -EFAULT; - - *entry = (void __user *)(uentry & ~1UL); - *pi = uentry & 1; - - return 0; -} - -/* - * Walk curr->robust_list (very carefully, it's a userspace list!) - * and mark any locks found there dead, and notify any waiters. - * - * We silently return on any sign of list-walking problem. - */ -static void exit_robust_list(struct task_struct *curr) -{ - struct robust_list_head __user *head = curr->robust_list; - struct robust_list __user *entry, *next_entry, *pending; - unsigned int limit = ROBUST_LIST_LIMIT, pi, pip; - unsigned int next_pi; - unsigned long futex_offset; - int rc; - - /* - * Fetch the list head (which was registered earlier, via - * sys_set_robust_list()): - */ - if (fetch_robust_entry(&entry, &head->list.next, &pi)) - return; - /* - * Fetch the relative futex offset: - */ - if (get_user(futex_offset, &head->futex_offset)) - return; - /* - * Fetch any possibly pending lock-add first, and handle it - * if it exists: - */ - if (fetch_robust_entry(&pending, &head->list_op_pending, &pip)) - return; - - next_entry = NULL; /* avoid warning with gcc */ - while (entry != &head->list) { - /* - * Fetch the next entry in the list before calling - * handle_futex_death: - */ - rc = fetch_robust_entry(&next_entry, &entry->next, &next_pi); - /* - * A pending lock might already be on the list, so - * don't process it twice: - */ - if (entry != pending) { - if (handle_futex_death((void __user *)entry + futex_offset, - curr, pi, HANDLE_DEATH_LIST)) - return; - } - if (rc) - return; - entry = next_entry; - pi = next_pi; - /* - * Avoid excessively long or circular lists: - */ - if (!--limit) - break; - - cond_resched(); - } - - if (pending) { - handle_futex_death((void __user *)pending + futex_offset, - curr, pip, HANDLE_DEATH_PENDING); - } -} - #ifdef CONFIG_COMPAT static void __user *futex_uaddr(struct robust_list __user *entry, compat_long_t futex_offset) @@ -5238,13 +3019,6 @@ compat_fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **ent return 0; } - -/* - * Walk curr->robust_list (very carefully, it's a userspace list!) - * and mark any locks found there dead, and notify any waiters. - * - * We silently return on any sign of list-walking problem. - */ static void compat_exit_robust_list(struct task_struct *curr) { struct compat_robust_list_head __user *head = curr->compat_robust_list; @@ -5254,26 +3028,6 @@ static void compat_exit_robust_list(struct task_struct *curr) compat_uptr_t uentry, next_uentry, upending; compat_long_t futex_offset; int rc; - - /* - * Fetch the list head (which was registered earlier, via - * sys_set_robust_list()): - */ - if (compat_fetch_robust_entry(&uentry, &entry, &head->list.next, &pi)) - return; - /* - * Fetch the relative futex offset: - */ - if (get_user(futex_offset, &head->futex_offset)) - return; - /* - * Fetch any possibly pending lock-add first, and handle it - * if it exists: - */ - if (compat_fetch_robust_entry(&upending, &pending, - &head->list_op_pending, &pip)) - return; - next_entry = NULL; /* avoid warning with gcc */ while (entry != (struct robust_list __user *) &head->list) { /* @@ -5316,40 +3070,17 @@ static void compat_exit_robust_list(struct task_struct *curr) #ifdef CONFIG_FUTEX_PI -/* - * This task is holding PI mutexes at exit time => bad. - * Kernel cleans up PI-state, but userspace is likely hosed. - * (Robust-futex cleanup is separate and might save the day for userspace.) - */ static void exit_pi_state_list(struct task_struct *curr) { struct list_head *next, *head = &curr->pi_state_list; struct futex_pi_state *pi_state; struct futex_hash_bucket *hb; union futex_key key = FUTEX_KEY_INIT; - - /* - * We are a ZOMBIE and nobody can enqueue itself on - * pi_state_list anymore, but we have to be careful - * versus waiters unqueueing themselves: - */ - raw_spin_lock_irq(&curr->pi_lock); while (!list_empty(head)) { next = head->next; pi_state = list_entry(next, struct futex_pi_state, list); key = pi_state->key; hb = futex_hash(&key); - - /* - * We can race against put_pi_state() removing itself from the - * list (a waiter going away). put_pi_state() will first - * decrement the reference count and then modify the list, so - * its possible to see the list entry but fail this reference - * acquire. - * - * In that case; drop the locks to let put_pi_state() make - * progress and retry the loop. - */ if (!refcount_inc_not_zero(&pi_state->refcount)) { raw_spin_unlock_irq(&curr->pi_lock); cpu_relax(); @@ -5410,24 +3141,6 @@ static void futex_cleanup(struct task_struct *tsk) if (unlikely(!list_empty(&tsk->pi_state_list))) exit_pi_state_list(tsk); } - -/** - * futex_exit_recursive - Set the tasks futex state to FUTEX_STATE_DEAD - * @tsk: task to set the state on - * - * Set the futex exit state of the task lockless. The futex waiter code - * observes that state when a task is exiting and loops until the task has - * actually finished the futex cleanup. The worst case for this is that the - * waiter runs through the wait loop until the state becomes visible. - * - * This is called from the recursive fault handling path in make_task_dead(). - * - * This is best effort. Either the futex exit code has run already or - * not. If the OWNER_DIED bit has been set on the futex then the waiter can - * take it over. If not, the problem is pushed back to user space. If the - * futex exit code did not run yet, then an already queued waiter might - * block forever, but there is nothing which can be done about that. - */ void futex_exit_recursive(struct task_struct *tsk) { /* If the state is FUTEX_STATE_EXITING then futex_exit_mutex is held */ @@ -5438,25 +3151,6 @@ void futex_exit_recursive(struct task_struct *tsk) static void futex_cleanup_begin(struct task_struct *tsk) { - /* - * Prevent various race issues against a concurrent incoming waiter - * including live locks by forcing the waiter to block on - * tsk->futex_exit_mutex when it observes FUTEX_STATE_EXITING in - * attach_to_pi_owner(). - */ - mutex_lock(&tsk->futex_exit_mutex); - - /* - * Switch the state to FUTEX_STATE_EXITING under tsk->pi_lock. - * - * This ensures that all subsequent checks of tsk->futex_state in - * attach_to_pi_owner() must observe FUTEX_STATE_EXITING with - * tsk->pi_lock held. - * - * It guarantees also that a pi_state which was queued right before - * the state change under tsk->pi_lock by a concurrent waiter must - * be observed in exit_pi_state_list(). - */ raw_spin_lock_irq(&tsk->pi_lock); tsk->futex_state = FUTEX_STATE_EXITING; raw_spin_unlock_irq(&tsk->pi_lock); @@ -5478,13 +3172,6 @@ static void futex_cleanup_end(struct task_struct *tsk, int state) void futex_exec_release(struct task_struct *tsk) { - /* - * The state handling is done for consistency, but in the case of - * exec() there is no way to prevent further damage as the PID stays - * the same. But for the unlikely and arguably buggy case that a - * futex is held on exec(), this provides at least as much state - * consistency protection which is possible. - */ futex_cleanup_begin(tsk); futex_cleanup(tsk); /* @@ -5512,7 +3199,7 @@ static int __init futex_init(void) futex_hashsize = roundup_pow_of_two(256 * num_possible_cpus()); #endif - futex_queues = alloc_large_system_hash("futex", sizeof(*futex_queues), + futex_queues = alloc_large_system_hash(, sizeof(*futex_queues), futex_hashsize, 0, 0, &futex_shift, NULL, futex_hashsize, futex_hashsize); diff --git a/ref_cpp b/ref_cpp index 45ee06c..986fe28 100644 --- a/ref_cpp +++ b/ref_cpp @@ -1,41 +1,7 @@ -// sol2 - -// The MIT License (MIT) - -// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors - -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef SOL_STACK_CORE_HPP #define SOL_STACK_CORE_HPP -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include #include #include @@ -79,10 +45,6 @@ namespace sol { } constexpr std::uintptr_t align(std::size_t alignment, std::uintptr_t ptr, std::size_t& space) { - // this handles arbitrary alignments... - // make this into a power-of-2-only? - // actually can't: this is a C++14-compatible framework, - // power of 2 alignment is C++17 std::uintptr_t offby = static_cast(ptr % alignment); std::uintptr_t padding = (alignment - offby) % alignment; ptr += padding; @@ -248,66 +210,11 @@ namespace sol { lua_pop(L, 1); // luaL_error(L, "if you are the one that wrote this allocator you should feel bad for doing a // worse job than malloc/realloc and should go read some books, yeah?"); - luaL_error(L, "cannot properly align memory for '%s'", detail::demangle().data()); + luaL_error(L, , detail::demangle().data()); } return static_cast(adjusted); } - inline bool attempt_alloc(lua_State* L, std::size_t ptr_align, std::size_t ptr_size, std::size_t value_align, - std::size_t allocated_size, void*& pointer_adjusted, void*& data_adjusted) { - void* adjusted = alloc_newuserdata(L, allocated_size); - pointer_adjusted = align(ptr_align, adjusted, allocated_size); - if (pointer_adjusted == nullptr) { - lua_pop(L, 1); - return false; - } - // subtract size of what we're going to allocate there - allocated_size -= ptr_size; - adjusted = static_cast(static_cast(pointer_adjusted) + ptr_size); - data_adjusted = align(value_align, adjusted, allocated_size); - if (data_adjusted == nullptr) { - lua_pop(L, 1); - return false; - } - return true; - } - - inline bool attempt_alloc_unique(lua_State* L, std::size_t ptr_align, std::size_t ptr_size, std::size_t real_align, - std::size_t allocated_size, void*& pointer_adjusted, void*& dx_adjusted, void*& id_adjusted, void*& data_adjusted) { - void* adjusted = alloc_newuserdata(L, allocated_size); - pointer_adjusted = align(ptr_align, adjusted, allocated_size); - if (pointer_adjusted == nullptr) { - lua_pop(L, 1); - return false; - } - allocated_size -= ptr_size; - - adjusted = static_cast(static_cast(pointer_adjusted) + ptr_size); - dx_adjusted = align(std::alignment_of_v, adjusted, allocated_size); - if (dx_adjusted == nullptr) { - lua_pop(L, 1); - return false; - } - allocated_size -= sizeof(unique_destructor); - - adjusted = static_cast(static_cast(dx_adjusted) + sizeof(unique_destructor)); - - id_adjusted = align(std::alignment_of_v, adjusted, allocated_size); - if (id_adjusted == nullptr) { - lua_pop(L, 1); - return false; - } - allocated_size -= sizeof(unique_tag); - - adjusted = static_cast(static_cast(id_adjusted) + sizeof(unique_tag)); - data_adjusted = align(real_align, adjusted, allocated_size); - if (data_adjusted == nullptr) { - lua_pop(L, 1); - return false; - } - return true; - } - template T* usertype_allocate(lua_State* L) { typedef std::integral_constant, sizeof(T*), std::alignment_of_v, initial_size, pointer_adjusted, data_adjusted); if (!result) { if (pointer_adjusted == nullptr) { - luaL_error(L, "aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle().c_str()); + luaL_error(L, , detail::demangle().c_str()); } else { - luaL_error(L, "aligned allocation of userdata block (data section) for '%s' failed", detail::demangle().c_str()); + luaL_error(L, , detail::demangle().c_str()); } return nullptr; } @@ -385,13 +292,13 @@ namespace sol { data_adjusted); if (!result) { if (pointer_adjusted == nullptr) { - luaL_error(L, "aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle().c_str()); + luaL_error(L, , detail::demangle().c_str()); } else if (dx_adjusted == nullptr) { - luaL_error(L, "aligned allocation of userdata block (deleter section) for '%s' failed", detail::demangle().c_str()); + luaL_error(L, , detail::demangle().c_str()); } else { - luaL_error(L, "aligned allocation of userdata block (data section) for '%s' failed", detail::demangle().c_str()); + luaL_error(L, , detail::demangle().c_str()); } return nullptr; } @@ -425,7 +332,7 @@ namespace sol { void* adjusted = align(std::alignment_of_v, unadjusted, allocated_size); if (adjusted == nullptr) { lua_pop(L, 1); - luaL_error(L, "cannot properly align memory for '%s'", detail::demangle().data()); + luaL_error(L, , detail::demangle().data()); } return static_cast(adjusted); } @@ -472,9 +379,9 @@ namespace sol { template int cannot_destroy(lua_State* L) { return luaL_error(L, - "cannot call the destructor for '%s': it is either hidden (protected/private) or removed with '= " - "delete' and thusly this type is being destroyed without properly destroying, invoking undefined " - "behavior: please bind a usertype and specify a custom destructor to define the behavior properly", + + + , detail::demangle().data()); } @@ -612,64 +519,17 @@ namespace sol { } // namespace stack - namespace meta { namespace meta_detail { - template - using adl_sol_lua_get_test_t = decltype(sol_lua_get(types(), static_cast(nullptr), -1, std::declval())); - - template - using adl_sol_lua_interop_get_test_t - = decltype(sol_lua_interop_get(types(), static_cast(nullptr), -1, static_cast(nullptr), std::declval())); - - template - using adl_sol_lua_check_test_t = decltype(sol_lua_check(types(), static_cast(nullptr), -1, &no_panic, std::declval())); - - template - using adl_sol_lua_interop_check_test_t - = decltype(sol_lua_interop_check(types(), static_cast(nullptr), -1, type::none, &no_panic, std::declval())); - - template - using adl_sol_lua_check_get_test_t - = decltype(sol_lua_check_get(types(), static_cast(nullptr), -1, &no_panic, std::declval())); - - template - using adl_sol_lua_push_test_t = decltype(sol_lua_push(static_cast(nullptr), std::declval()...)); - - template - using adl_sol_lua_push_exact_test_t = decltype(sol_lua_push(types(), static_cast(nullptr), std::declval()...)); - - template - inline constexpr bool is_adl_sol_lua_get_v = meta::is_detected_v; - - template - inline constexpr bool is_adl_sol_lua_interop_get_v = meta::is_detected_v; - - template - inline constexpr bool is_adl_sol_lua_check_v = meta::is_detected_v; - - template - inline constexpr bool is_adl_sol_lua_interop_check_v = meta::is_detected_v; - - template - inline constexpr bool is_adl_sol_lua_check_get_v = meta::is_detected_v; - - template - inline constexpr bool is_adl_sol_lua_push_v = meta::is_detected_v; - - template - inline constexpr bool is_adl_sol_lua_push_exact_v = meta::is_detected_v; - }} // namespace meta::meta_detail - namespace stack { namespace stack_detail { - constexpr const char* not_enough_stack_space = "not enough space left on Lua stack"; - constexpr const char* not_enough_stack_space_floating = "not enough space left on Lua stack for a floating point number"; - constexpr const char* not_enough_stack_space_integral = "not enough space left on Lua stack for an integral number"; - constexpr const char* not_enough_stack_space_string = "not enough space left on Lua stack for a string"; - constexpr const char* not_enough_stack_space_meta_function_name = "not enough space left on Lua stack for the name of a meta_function"; - constexpr const char* not_enough_stack_space_userdata = "not enough space left on Lua stack to create a sol2 userdata"; - constexpr const char* not_enough_stack_space_generic = "not enough space left on Lua stack to push valuees"; - constexpr const char* not_enough_stack_space_environment = "not enough space left on Lua stack to retrieve environment"; + constexpr const char* not_enough_stack_space = ; + constexpr const char* not_enough_stack_space_floating = ; + constexpr const char* not_enough_stack_space_integral = ; + constexpr const char* not_enough_stack_space_string = ; + constexpr const char* not_enough_stack_space_meta_function_name = ; + constexpr const char* not_enough_stack_space_userdata = ; + constexpr const char* not_enough_stack_space_generic = ; + constexpr const char* not_enough_stack_space_environment = ; template struct strip { @@ -1344,8 +1204,8 @@ namespace sol { template int member_default_to_string(std::false_type, lua_State* L) { return luaL_error(L, - "cannot perform to_string on '%s': no 'to_string' overload in namespace, 'to_string' member " - "function, or operator<<(ostream&, ...) present", + + , detail::demangle().data()); } @@ -1445,34 +1305,6 @@ namespace sol { #endif // SOL_STACK_CORE_HPP -// sol2 - -// The MIT License (MIT) - -// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors - -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -#ifndef SOL_TIE_HPP -#define SOL_TIE_HPP - -#include - namespace sol { namespace detail { @@ -1544,36 +1376,6 @@ namespace sol { #endif // SOL_TIE_HPP -// sol2 - -// The MIT License (MIT) - -// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors - -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -#ifndef SOL_USERTYPE_CONTAINER_HPP -#define SOL_USERTYPE_CONTAINER_HPP - -#include -#include -#include - namespace sol { template @@ -1593,438 +1395,6 @@ namespace sol { static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; }; - template - struct has_empty_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::empty)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_erase_after_test { - private: - template - static meta::sfinae_yes_t test( - decltype(std::declval().erase_after(std::declval>()))*); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_find_test { - private: - template - static meta::sfinae_yes_t test(decltype(std::declval().find(std::declval>()))*); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_find_test::value>> { - private: - template - static meta::sfinae_yes_t test(decltype(std::declval().find(std::declval>()))*); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_erase_test { - private: - template - static meta::sfinae_yes_t test(decltype(std::declval().erase(std::declval()))*); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_erase_key_test { - private: - template - static meta::sfinae_yes_t test(decltype(std::declval().erase(std::declval()))*); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_find_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::find)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_index_of_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::index_of)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_insert_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::insert)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_erase_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::erase)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_index_set_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::index_set)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_index_get_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::index_get)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_set_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::set)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_get_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::get)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_at_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::at)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_pairs_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::pairs)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_ipairs_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::ipairs)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_next_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::next)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_add_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::add)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - struct has_traits_size_test { - private: - template - static meta::sfinae_yes_t test(decltype(&C::size)); - template - static meta::sfinae_no_t test(...); - - public: - static constexpr bool value = std::is_same_v(0)), meta::sfinae_yes_t>; - }; - - template - using has_clear = meta::boolean::value>; - - template - using has_empty = meta::boolean::value>; - - template - using has_find = meta::boolean::value>; - - template - using has_erase = meta::boolean::value>; - - template - using has_erase_key = meta::boolean::value>; - - template - using has_erase_after = meta::boolean::value>; - - template - using has_traits_get = meta::boolean::value>; - - template - using has_traits_at = meta::boolean::value>; - - template - using has_traits_set = meta::boolean::value>; - - template - using has_traits_index_get = meta::boolean::value>; - - template - using has_traits_index_set = meta::boolean::value>; - - template - using has_traits_pairs = meta::boolean::value>; - - template - using has_traits_ipairs = meta::boolean::value>; - - template - using has_traits_next = meta::boolean::value>; - - template - using has_traits_add = meta::boolean::value>; - - template - using has_traits_size = meta::boolean::value>; - - template - using has_traits_clear = has_clear; - - template - using has_traits_empty = has_empty; - - template - using has_traits_find = meta::boolean::value>; - - template - using has_traits_index_of = meta::boolean::value>; - - template - using has_traits_insert = meta::boolean::value>; - - template - using has_traits_erase = meta::boolean::value>; - - template - struct is_forced_container : is_container { }; - - template - struct is_forced_container> : std::true_type { }; - - template - struct container_decay { - typedef T type; - }; - - template - struct container_decay> { - typedef T type; - }; - - template - using container_decay_t = typename container_decay>::type; - - template - decltype(auto) get_key(std::false_type, T&& t) { - return std::forward(t); - } - - template - decltype(auto) get_key(std::true_type, T&& t) { - return t.first; - } - - template - decltype(auto) get_value(std::false_type, T&& t) { - return std::forward(t); - } - - template - decltype(auto) get_value(std::true_type, T&& t) { - return t.second; - } - - template - struct usertype_container_default { - private: - typedef std::remove_pointer_t> T; - - public: - typedef lua_nil_t iterator; - typedef iterator sentinel; - typedef lua_nil_t value_type; - - static int at(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'at(index)' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int get(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'get(key)' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int index_get(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'container[key]' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int set(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'set(key, value)' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int index_set(lua_State* L_) { - return luaL_error( - L_, "sol: cannot call 'container[key] = value' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int add(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'add' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int insert(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'insert' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int find(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'find' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int index_of(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'index_of' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int size(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'end' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int clear(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'clear' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int empty(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'empty' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int erase(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'erase' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int next(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'next' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int pairs(lua_State* L_) { - return luaL_error(L_, "sol: cannot call '__pairs/pairs' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static int ipairs(lua_State* L_) { - return luaL_error(L_, "sol: cannot call '__ipairs' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - } - - static iterator begin(lua_State* L_, T&) { - luaL_error(L_, "sol: cannot call 'being' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - return lua_nil; - } - - static sentinel end(lua_State* L_, T&) { - luaL_error(L_, "sol: cannot call 'end' on type '%s': it is not recognized as a container", detail::demangle().c_str()); - return lua_nil; - } - }; - template struct usertype_container_default>, meta::has_value_type>>, @@ -2091,12 +1461,12 @@ namespace sol { auto p = stack::unqualified_check_get(L_, 1); if (!p) { luaL_error(L_, - "sol: 'self' is not of type '%s' (pass 'self' as first argument with ':' or call on proper type)", + , detail::demangle().c_str()); } if (p.value() == nullptr) { luaL_error( - L_, "sol: 'self' argument is nil (pass 'self' as first argument with ':' or call on a '%s' type)", detail::demangle().c_str()); + L_, , detail::demangle().c_str()); } return *p.value(); #else @@ -2194,7 +1564,7 @@ namespace sol { } static detail::error_result get_comparative(std::false_type, lua_State*, T&, K&) { - return detail::error_result("cannot get this key on '%s': no suitable way to increment iterator and compare to key value '%s'", + return detail::error_result(, detail::demangle().data(), detail::demangle().data()); } @@ -2221,7 +1591,7 @@ namespace sol { static detail::error_result set_writable(std::false_type, lua_State*, T&, iterator&, stack_object) { return detail::error_result( - "cannot perform a 'set': '%s's iterator reference is not writable (non-copy-assignable or const)", detail::demangle().data()); + , detail::demangle().data()); } static detail::error_result set_category(std::input_iterator_tag, lua_State* L_, T& self, stack_object okey, stack_object value) { @@ -2237,7 +1607,7 @@ namespace sol { if (key == 0) { return add_copyable(is_copyable(), L_, self, std::move(value), meta::has_insert_after::value ? backit : it); } - return detail::error_result("out of bounds (too big) for set on '%s'", detail::demangle().c_str()); + return detail::error_result(, detail::demangle().c_str()); } return set_writable(is_writable(), L_, self, it, std::move(value)); } @@ -2246,14 +1616,14 @@ namespace sol { decltype(auto) key = okey.as(); key = static_cast(static_cast(key) + deferred_uc::index_adjustment(L_, self)); if (key < 0) { - return detail::error_result("sol: out of bounds (too small) for set on '%s'", detail::demangle().c_str()); + return detail::error_result(, detail::demangle().c_str()); } std::ptrdiff_t len = static_cast(size_start(L_, self)); if (key == len) { return add_copyable(is_copyable(), L_, self, std::move(value)); } else if (key >= len) { - return detail::error_result("sol: out of bounds (too big) for set on '%s'", detail::demangle().c_str()); + return detail::error_result(, detail::demangle().c_str()); } auto it = std::next(deferred_uc::begin(L_, self), key); return set_writable(is_writable(), L_, self, it, std::move(value)); @@ -2263,7 +1633,7 @@ namespace sol { decltype(auto) key = okey.as(); if (!is_writable::value) { return detail::error_result( - "cannot perform a 'set': '%s's iterator reference is not writable (non-copy-assignable or const)", detail::demangle().data()); + , detail::demangle().data()); } auto fx = [&](const value_type& r) -> bool { return key == get_key(is_associative(), r); }; auto e = deferred_uc::end(L_, self); @@ -2275,7 +1645,7 @@ namespace sol { } static detail::error_result set_comparative(std::false_type, lua_State*, T&, stack_object, stack_object) { - return detail::error_result("cannot set this value on '%s': no suitable way to increment iterator or compare to '%s' key", + return detail::error_result(, detail::demangle().data(), detail::demangle().data()); } @@ -2295,7 +1665,7 @@ namespace sol { (void)it; (void)key; return detail::error_result( - "cannot call 'set' on '%s': there is no 'insert' function on this associative type", detail::demangle().c_str()); + , detail::demangle().c_str()); } } @@ -2314,7 +1684,7 @@ namespace sol { (void)it; (void)key; return detail::error_result( - "cannot call 'set' on '%s': there is no 'insert' function on this non-associative type", detail::demangle().c_str()); + , detail::demangle().c_str()); } } @@ -2344,7 +1714,7 @@ namespace sol { if constexpr (!is_ordered::value && idx_of) { (void)L_; (void)self; - return detail::error_result("cannot perform an 'index_of': '%s's is not an ordered container", detail::demangle().data()); + return detail::error_result(, detail::demangle().data()); } else { decltype(auto) key = stack::unqualified_get(L_, 2); @@ -2368,7 +1738,7 @@ namespace sol { if constexpr (!is_ordered::value && idx_of) { (void)L_; (void)self; - return detail::error_result("cannot perform an 'index_of': '%s's is not an ordered container", detail::demangle().data()); + return detail::error_result(, detail::demangle().data()); } else { decltype(auto) value = stack::unqualified_get(L_, 2); @@ -2405,7 +1775,7 @@ namespace sol { template static detail::error_result find_comparative(std::false_type, lua_State*, T&) { - return detail::error_result("cannot call 'find' on '%s': there is no 'find' function and the value_type is not equality comparable", + return detail::error_result(, detail::demangle().c_str()); } @@ -2437,7 +1807,7 @@ namespace sol { } static detail::error_result add_insert_after(std::false_type, lua_State*, T&, stack_object) { - return detail::error_result("cannot call 'add' on type '%s': no suitable insert/push_back C++ functions", detail::demangle().data()); + return detail::error_result(, detail::demangle().data()); } template @@ -2513,7 +1883,7 @@ namespace sol { (void)key; (void)pos; return detail::error_result( - "cannot call 'insert' on '%s': there is no 'insert' function on this associative type", detail::demangle().c_str()); + , detail::demangle().c_str()); } } @@ -2546,7 +1916,7 @@ namespace sol { } static detail::error_result add_copyable(std::false_type, lua_State*, T&, stack_object) { - return detail::error_result("cannot call 'add' on '%s': value_type is non-copyable", detail::demangle().data()); + return detail::error_result(, detail::demangle().data()); } static detail::error_result insert_lookup(std::true_type, lua_State* L_, T& self, stack_object, stack_object value) { @@ -2571,7 +1941,7 @@ namespace sol { auto e = deferred_uc::end(L_, self); for (auto it = deferred_uc::begin(L_, self); key > 0; ++backit, ++it, --key) { if (backit == e) { - return detail::error_result("sol: out of bounds (too big) for set on '%s'", detail::demangle().c_str()); + return detail::error_result(, detail::demangle().c_str()); } } } @@ -2581,7 +1951,7 @@ namespace sol { static detail::error_result insert_after_has(std::false_type, lua_State*, T&, stack_object, stack_object) { return detail::error_result( - "cannot call 'insert' on '%s': no suitable or similar functionality detected on this container", detail::demangle().data()); + , detail::demangle().data()); } static detail::error_result insert_has(std::true_type, lua_State* L_, T& self, stack_object key, stack_object value) { @@ -2602,7 +1972,7 @@ namespace sol { } static detail::error_result insert_copyable(std::false_type, lua_State*, T&, stack_object, stack_object) { - return detail::error_result("cannot call 'insert' on '%s': value_type is non-copyable", detail::demangle().data()); + return detail::error_result(, detail::demangle().data()); } static detail::error_result erase_integral(std::true_type, lua_State* L_, T& self, K& key) { @@ -2642,7 +2012,7 @@ namespace sol { auto e = deferred_uc::end(L_, self); for (auto it = deferred_uc::begin(L_, self); key > 0; ++backit, ++it, --key) { if (backit == e) { - return detail::error_result("sol: out of bounds for erase on '%s'", detail::demangle().c_str()); + return detail::error_result(, detail::demangle().c_str()); } } } @@ -2651,7 +2021,7 @@ namespace sol { } static detail::error_result erase_after_has(std::false_type, lua_State*, T&, const K&) { - return detail::error_result("sol: cannot call erase on '%s'", detail::demangle().c_str()); + return detail::error_result(, detail::demangle().c_str()); } static detail::error_result erase_key_has(std::true_type, lua_State* L_, T& self, K& key) { @@ -2683,7 +2053,7 @@ namespace sol { } static void clear_has(std::false_type, lua_State* L_, T&) { - luaL_error(L_, "sol: cannot call clear on '%s'", detail::demangle().c_str()); + luaL_error(L_, , detail::demangle().c_str()); } static bool empty_has(std::true_type, lua_State*, T& self) { @@ -2978,197 +2348,6 @@ namespace sol { } }; - static auto& get_src(lua_State* L_) { - auto p = stack::unqualified_check_get(L_, 1); -#if SOL_IS_ON(SOL_SAFE_USERTYPE) - if (!p) { - luaL_error(L_, - "sol: 'self' is not of type '%s' (pass 'self' as first argument with ':' or call on proper type)", - detail::demangle().c_str()); - } - if (p.value() == nullptr) { - luaL_error( - L_, "sol: 'self' argument is nil (pass 'self' as first argument with ':' or call on a '%s' type)", detail::demangle().c_str()); - } -#endif // Safe getting with error - return *p.value(); - } - - static int find(std::true_type, lua_State* L_) { - T& self = get_src(L_); - decltype(auto) value = stack::unqualified_get(L_, 2); - std::size_t N = std::extent::value; - for (std::size_t idx = 0; idx < N; ++idx) { - using v_t = std::add_const_t; - v_t v = self[idx]; - if (v == value) { - idx = static_cast(static_cast(idx) - deferred_uc::index_adjustment(L_, self)); - return stack::push(L_, idx); - } - } - return stack::push(L_, lua_nil); - } - - static int find(std::false_type, lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'find' on '%s': no supported comparison operator for the value type", detail::demangle().c_str()); - } - - static int next_iter(lua_State* L_) { - iter& i = stack::unqualified_get>(L_, 1); - auto& it = i.it(); - auto& end = i.sen(); - std::size_t k = stack::unqualified_get(L_, 2); - if (it == end) { - return 0; - } - int p; - p = stack::push(L_, k + 1); - p += stack::push_reference(L_, detail::deref_move_only(*it)); - std::advance(it, 1); - return p; - } - - public: - static int clear(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'clear' on type '%s': cannot remove all items from a fixed array", detail::demangle().c_str()); - } - - static int erase(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'erase' on type '%s': cannot remove an item from fixed arrays", detail::demangle().c_str()); - } - - static int add(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'add' on type '%s': cannot add to fixed arrays", detail::demangle().c_str()); - } - - static int insert(lua_State* L_) { - return luaL_error(L_, "sol: cannot call 'insert' on type '%s': cannot insert new entries into fixed arrays", detail::demangle().c_str()); - } - - static int at(lua_State* L_) { - return get(L_); - } - - static int get(lua_State* L_) { - T& self = get_src(L_); - std::ptrdiff_t idx = stack::unqualified_get(L_, 2); - idx += deferred_uc::index_adjustment(L_, self); - if (idx >= static_cast(std::extent::value) || idx < 0) { - return stack::push(L_, lua_nil); - } - return stack::push_reference(L_, detail::deref_move_only(self[idx])); - } - - static int index_get(lua_State* L_) { - return get(L_); - } - - static int set(lua_State* L_) { - T& self = get_src(L_); - std::ptrdiff_t idx = stack::unqualified_get(L_, 2); - idx += deferred_uc::index_adjustment(L_, self); - if (idx >= static_cast(std::extent::value)) { - return luaL_error(L_, "sol: index out of bounds (too big) for set on '%s'", detail::demangle().c_str()); - } - if (idx < 0) { - return luaL_error(L_, "sol: index out of bounds (too small) for set on '%s'", detail::demangle().c_str()); - } - self[idx] = stack::unqualified_get(L_, 3); - return 0; - } - - static int index_set(lua_State* L_) { - return set(L_); - } - - static int index_of(lua_State* L_) { - return find(L_); - } - - static int find(lua_State* L_) { - return find(meta::supports_op_equal(), L_); - } - - static int size(lua_State* L_) { - return stack::push(L_, std::extent::value); - } - - static int empty(lua_State* L_) { - return stack::push(L_, std::extent::value > 0); - } - - static int pairs(lua_State* L_) { - auto& src = get_src(L_); - stack::push(L_, next_iter); - stack::push>(L_, L_, 1, deferred_uc::begin(L_, src), deferred_uc::end(L_, src)); - stack::push(L_, 0); - return 3; - } - - static int ipairs(lua_State* L_) { - return pairs(L_); - } - - static int next(lua_State* L_) { - return stack::push(L_, next_iter); - } - - static std::ptrdiff_t index_adjustment(lua_State*, T&) { - return (SOL_CONTAINER_START_INDEX_I_) == 0 ? 0 : -(SOL_CONTAINER_START_INDEX_I_); - } - - static iterator begin(lua_State*, T& self) { - return std::addressof(self[0]); - } - - static sentinel end(lua_State*, T& self) { - return std::addressof(self[0]) + std::extent::value; - } - }; - - template - struct usertype_container_default> : usertype_container_default { }; - } // namespace container_detail - - template - struct usertype_container : container_detail::usertype_container_default { }; - -} // namespace sol - -#endif // SOL_USERTYPE_CONTAINER_HPP - -// sol2 - -// The MIT License (MIT) - -// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors - -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -#ifndef SOL_POINTER_LIKE_HPP -#define SOL_POINTER_LIKE_HPP - -#include - -#include -#include -#include - namespace sol { namespace meta { @@ -3241,320 +2420,6 @@ namespace sol { #endif // SOL_POINTER_LIKE_HPP -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_VECTOR -#define _LIBCPP_VECTOR - -/* - vector synopsis - -namespace std -{ - -template > -class vector -{ -public: - typedef T value_type; - typedef Allocator allocator_type; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - typedef implementation-defined iterator; - typedef implementation-defined const_iterator; - typedef typename allocator_type::size_type size_type; - typedef typename allocator_type::difference_type difference_type; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - - vector() - noexcept(is_nothrow_default_constructible::value); - explicit vector(const allocator_type&); - explicit vector(size_type n); - explicit vector(size_type n, const allocator_type&); // C++14 - vector(size_type n, const value_type& value, const allocator_type& = allocator_type()); - template - vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type()); - vector(const vector& x); - vector(vector&& x) - noexcept(is_nothrow_move_constructible::value); - vector(initializer_list il); - vector(initializer_list il, const allocator_type& a); - ~vector(); - vector& operator=(const vector& x); - vector& operator=(vector&& x) - noexcept( - allocator_type::propagate_on_container_move_assignment::value || - allocator_type::is_always_equal::value); // C++17 - vector& operator=(initializer_list il); - template - void assign(InputIterator first, InputIterator last); - void assign(size_type n, const value_type& u); - void assign(initializer_list il); - - allocator_type get_allocator() const noexcept; - - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; - - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; - - size_type size() const noexcept; - size_type max_size() const noexcept; - size_type capacity() const noexcept; - bool empty() const noexcept; - void reserve(size_type n); - void shrink_to_fit() noexcept; - - reference operator[](size_type n); - const_reference operator[](size_type n) const; - reference at(size_type n); - const_reference at(size_type n) const; - - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; - - value_type* data() noexcept; - const value_type* data() const noexcept; - - void push_back(const value_type& x); - void push_back(value_type&& x); - template - reference emplace_back(Args&&... args); // reference in C++17 - void pop_back(); - - template iterator emplace(const_iterator position, Args&&... args); - iterator insert(const_iterator position, const value_type& x); - iterator insert(const_iterator position, value_type&& x); - iterator insert(const_iterator position, size_type n, const value_type& x); - template - iterator insert(const_iterator position, InputIterator first, InputIterator last); - iterator insert(const_iterator position, initializer_list il); - - iterator erase(const_iterator position); - iterator erase(const_iterator first, const_iterator last); - - void clear() noexcept; - - void resize(size_type sz); - void resize(size_type sz, const value_type& c); - - void swap(vector&) - noexcept(allocator_traits::propagate_on_container_swap::value || - allocator_traits::is_always_equal::value); // C++17 - - bool __invariants() const; -}; - -template > -class vector -{ -public: - typedef bool value_type; - typedef Allocator allocator_type; - typedef implementation-defined iterator; - typedef implementation-defined const_iterator; - typedef typename allocator_type::size_type size_type; - typedef typename allocator_type::difference_type difference_type; - typedef iterator pointer; - typedef const_iterator const_pointer; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - - class reference - { - public: - reference(const reference&) noexcept; - operator bool() const noexcept; - reference& operator=(bool x) noexcept; - reference& operator=(const reference& x) noexcept; - iterator operator&() const noexcept; - void flip() noexcept; - }; - - class const_reference - { - public: - const_reference(const reference&) noexcept; - operator bool() const noexcept; - const_iterator operator&() const noexcept; - }; - - vector() - noexcept(is_nothrow_default_constructible::value); - explicit vector(const allocator_type&); - explicit vector(size_type n, const allocator_type& a = allocator_type()); // C++14 - vector(size_type n, const value_type& value, const allocator_type& = allocator_type()); - template - vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type()); - vector(const vector& x); - vector(vector&& x) - noexcept(is_nothrow_move_constructible::value); - vector(initializer_list il); - vector(initializer_list il, const allocator_type& a); - ~vector(); - vector& operator=(const vector& x); - vector& operator=(vector&& x) - noexcept( - allocator_type::propagate_on_container_move_assignment::value || - allocator_type::is_always_equal::value); // C++17 - vector& operator=(initializer_list il); - template - void assign(InputIterator first, InputIterator last); - void assign(size_type n, const value_type& u); - void assign(initializer_list il); - - allocator_type get_allocator() const noexcept; - - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; - - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; - - size_type size() const noexcept; - size_type max_size() const noexcept; - size_type capacity() const noexcept; - bool empty() const noexcept; - void reserve(size_type n); - void shrink_to_fit() noexcept; - - reference operator[](size_type n); - const_reference operator[](size_type n) const; - reference at(size_type n); - const_reference at(size_type n) const; - - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; - - void push_back(const value_type& x); - template reference emplace_back(Args&&... args); // C++14; reference in C++17 - void pop_back(); - - template iterator emplace(const_iterator position, Args&&... args); // C++14 - iterator insert(const_iterator position, const value_type& x); - iterator insert(const_iterator position, size_type n, const value_type& x); - template - iterator insert(const_iterator position, InputIterator first, InputIterator last); - iterator insert(const_iterator position, initializer_list il); - - iterator erase(const_iterator position); - iterator erase(const_iterator first, const_iterator last); - - void clear() noexcept; - - void resize(size_type sz); - void resize(size_type sz, value_type x); - - void swap(vector&) - noexcept(allocator_traits::propagate_on_container_swap::value || - allocator_traits::is_always_equal::value); // C++17 - void flip() noexcept; - - bool __invariants() const; -}; - -template ::value_type>> - vector(InputIterator, InputIterator, Allocator = Allocator()) - -> vector::value_type, Allocator>; // C++17 - -template struct hash>; - -template bool operator==(const vector& x, const vector& y); -template bool operator< (const vector& x, const vector& y); -template bool operator!=(const vector& x, const vector& y); -template bool operator> (const vector& x, const vector& y); -template bool operator>=(const vector& x, const vector& y); -template bool operator<=(const vector& x, const vector& y); - -template -void swap(vector& x, vector& y) - noexcept(noexcept(x.swap(y))); - -template -typename vector::size_type -erase(vector& c, const U& value); // C++20 -template -typename vector::size_type -erase_if(vector& c, Predicate pred); // C++20 - - -template - inline constexpr bool is-vector-bool-reference = see below; // exposition only, since C++23 - -template requires is-vector-bool-reference // Since C++23 - struct formatter; - -} // std - -*/ - -#include <__algorithm/copy.h> -#include <__algorithm/equal.h> -#include <__algorithm/fill_n.h> -#include <__algorithm/lexicographical_compare.h> -#include <__algorithm/remove.h> -#include <__algorithm/remove_if.h> -#include <__algorithm/rotate.h> -#include <__algorithm/unwrap_iter.h> -#include <__assert> // all public C++ headers provide the assertion handler -#include <__bit_reference> -#include <__concepts/same_as.h> -#include <__config> -#include <__debug> -#include <__format/enable_insertable.h> -#include <__format/formatter.h> -#include <__functional/hash.h> -#include <__functional/unary_function.h> -#include <__iterator/advance.h> -#include <__iterator/iterator_traits.h> -#include <__iterator/reverse_iterator.h> -#include <__iterator/wrap_iter.h> -#include <__memory/allocate_at_least.h> -#include <__memory/pointer_traits.h> -#include <__memory/swap_allocator.h> -#include <__memory/temp_value.h> -#include <__memory/uninitialized_algorithms.h> -#include <__memory_resource/polymorphic_allocator.h> -#include <__split_buffer> -#include <__type_traits/is_allocator.h> -#include <__type_traits/noexcept_move_assign_container.h> -#include <__utility/exception_guard.h> -#include <__utility/forward.h> -#include <__utility/move.h> -#include <__utility/swap.h> #include #include #include @@ -3564,29 +2429,6 @@ template requires is-vector-bool-reference // Since C++ #include #include -// standard-mandated includes - -// [iterator.range] -#include <__iterator/access.h> -#include <__iterator/data.h> -#include <__iterator/empty.h> -#include <__iterator/reverse_access.h> -#include <__iterator/size.h> - -// [vector.syn] -#include -#include - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - - -_LIBCPP_BEGIN_NAMESPACE_STD - template */> class _LIBCPP_TEMPLATE_VIS vector { @@ -3610,11 +2452,11 @@ public: typedef std::reverse_iterator const_reverse_iterator; static_assert((is_same::value), - "Allocator::value_type must be same type as value_type"); + ); static_assert(is_same >::value, - "[allocator.requirements] states that rebinding an allocator to the same type should result in the " - "original allocator"); + + ); _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector() _NOEXCEPT_(is_nothrow_default_constructible::value) @@ -3631,12 +2473,6 @@ public: { std::__debug_db_insert_c(this); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n); -#if _LIBCPP_STD_VER > 11 - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n, const allocator_type& __a); -#endif - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(size_type __n, const value_type& __x); - template ::value> > _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(size_type __n, const value_type& __x, const allocator_type& __a) @@ -3797,595 +2633,6 @@ public: _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n); _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT; - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference operator[](size_type __n) _NOEXCEPT; - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __n) const _NOEXCEPT; - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference at(size_type __n); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __n) const; - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT - { - _LIBCPP_ASSERT(!empty(), "front() called on an empty vector"); - return *this->__begin_; - } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT - { - _LIBCPP_ASSERT(!empty(), "front() called on an empty vector"); - return *this->__begin_; - } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT - { - _LIBCPP_ASSERT(!empty(), "back() called on an empty vector"); - return *(this->__end_ - 1); - } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT - { - _LIBCPP_ASSERT(!empty(), "back() called on an empty vector"); - return *(this->__end_ - 1); - } - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - value_type* data() _NOEXCEPT - {return std::__to_address(this->__begin_);} - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - const value_type* data() const _NOEXCEPT - {return std::__to_address(this->__begin_);} - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(const_reference __x); - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x); - - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI -#if _LIBCPP_STD_VER > 14 - reference emplace_back(_Args&&... __args); -#else - void emplace_back(_Args&&... __args); -#endif - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void pop_back(); - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __position, const_reference __x); - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __position, value_type&& __x); - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __position, _Args&&... __args); - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - iterator insert(const_iterator __position, size_type __n, const_reference __x); - - template ::value && - is_constructible< value_type, typename iterator_traits<_InputIterator>::reference>::value, - int> = 0> - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator - insert(const_iterator __position, _InputIterator __first, _InputIterator __last); - - template < - class _ForwardIterator, - __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value && - is_constructible< value_type, typename iterator_traits<_ForwardIterator>::reference>::value, - int> = 0> - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator - insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last); - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - iterator insert(const_iterator __position, initializer_list __il) - {return insert(__position, __il.begin(), __il.end());} -#endif - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __position); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last); - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void clear() _NOEXCEPT - { - size_type __old_size = size(); - __clear(); - __annotate_shrink(__old_size); - std::__debug_db_invalidate_all(this); - } - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz, const_reference __x); - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(vector&) -#if _LIBCPP_STD_VER >= 14 - _NOEXCEPT; -#else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || - __is_nothrow_swappable::value); -#endif - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const; - -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - - bool __dereferenceable(const const_iterator* __i) const; - bool __decrementable(const const_iterator* __i) const; - bool __addable(const const_iterator* __i, ptrdiff_t __n) const; - bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; - -#endif // _LIBCPP_ENABLE_DEBUG_MODE - -private: - pointer __begin_ = nullptr; - pointer __end_ = nullptr; - __compressed_pair __end_cap_ = - __compressed_pair(nullptr, __default_init_tag()); - - _LIBCPP_HIDE_FROM_ABI void __invalidate_iterators_past(pointer __new_last); - - // Allocate space for __n objects - // throws length_error if __n > max_size() - // throws (probably bad_alloc) if memory run out - // Precondition: __begin_ == __end_ == __end_cap() == 0 - // Precondition: __n > 0 - // Postcondition: capacity() >= __n - // Postcondition: size() == 0 - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __vallocate(size_type __n) { - if (__n > max_size()) - __throw_length_error(); - auto __allocation = std::__allocate_at_least(__alloc(), __n); - __begin_ = __allocation.ptr; - __end_ = __allocation.ptr; - __end_cap() = __begin_ + __allocation.count; - __annotate_new(0); - } - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __vdeallocate() _NOEXCEPT; - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __recommend(size_type __new_size) const; - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __construct_at_end(size_type __n, const_reference __x); - - template ::value, int> = 0> - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void - __construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n); - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - iterator __make_iter(pointer __p) _NOEXCEPT { return iterator(this, __p); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - const_iterator __make_iter(const_pointer __p) const _NOEXCEPT { return const_iterator(this, __p); } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_out_circular_buffer(__split_buffer& __v); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __swap_out_circular_buffer(__split_buffer& __v, pointer __p); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_range(pointer __from_s, pointer __from_e, pointer __to); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign(vector& __c, true_type) - _NOEXCEPT_(is_nothrow_move_assignable::value); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign(vector& __c, false_type) - _NOEXCEPT_(__alloc_traits::is_always_equal::value); - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __destruct_at_end(pointer __new_last) _NOEXCEPT - { - if (!__libcpp_is_constant_evaluated()) - __invalidate_iterators_past(__new_last); - size_type __old_size = size(); - __base_destruct_at_end(__new_last); - __annotate_shrink(__old_size); - } - - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - inline void __push_back_slow_path(_Up&& __x); - - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - inline void __emplace_back_slow_path(_Args&&... __args); - - // The following functions are no-ops outside of AddressSanitizer mode. - // We call annotatations only for the default Allocator because other allocators - // may not meet the AddressSanitizer alignment constraints. - // See the documentation for __sanitizer_annotate_contiguous_container for more details. -#ifndef _LIBCPP_HAS_NO_ASAN - _LIBCPP_CONSTEXPR_SINCE_CXX20 - void __annotate_contiguous_container(const void *__beg, const void *__end, - const void *__old_mid, - const void *__new_mid) const - { - - if (!__libcpp_is_constant_evaluated() && __beg && is_same::value) - __sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid); - } -#else - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __annotate_contiguous_container(const void*, const void*, const void*, - const void*) const _NOEXCEPT {} -#endif - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __annotate_new(size_type __current_size) const _NOEXCEPT { - __annotate_contiguous_container(data(), data() + capacity(), - data() + capacity(), data() + __current_size); - } - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __annotate_delete() const _NOEXCEPT { - __annotate_contiguous_container(data(), data() + capacity(), - data() + size(), data() + capacity()); - } - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __annotate_increase(size_type __n) const _NOEXCEPT - { - __annotate_contiguous_container(data(), data() + capacity(), - data() + size(), data() + size() + __n); - } - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __annotate_shrink(size_type __old_size) const _NOEXCEPT - { - __annotate_contiguous_container(data(), data() + capacity(), - data() + __old_size, data() + size()); - } - - struct _ConstructTransaction { - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - explicit _ConstructTransaction(vector &__v, size_type __n) - : __v_(__v), __pos_(__v.__end_), __new_end_(__v.__end_ + __n) { -#ifndef _LIBCPP_HAS_NO_ASAN - __v_.__annotate_increase(__n); -#endif - } - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { - __v_.__end_ = __pos_; -#ifndef _LIBCPP_HAS_NO_ASAN - if (__pos_ != __new_end_) { - __v_.__annotate_shrink(__new_end_ - __v_.__begin_); - } -#endif - } - - vector &__v_; - pointer __pos_; - const_pointer const __new_end_; - - private: - _ConstructTransaction(_ConstructTransaction const&) = delete; - _ConstructTransaction& operator=(_ConstructTransaction const&) = delete; - }; - - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __construct_one_at_end(_Args&& ...__args) { - _ConstructTransaction __tx(*this, 1); - __alloc_traits::construct(this->__alloc(), std::__to_address(__tx.__pos_), - std::forward<_Args>(__args)...); - ++__tx.__pos_; - } - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - allocator_type& __alloc() _NOEXCEPT - {return this->__end_cap_.second();} - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - const allocator_type& __alloc() const _NOEXCEPT - {return this->__end_cap_.second();} - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - pointer& __end_cap() _NOEXCEPT - {return this->__end_cap_.first();} - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - const pointer& __end_cap() const _NOEXCEPT - {return this->__end_cap_.first();} - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __clear() _NOEXCEPT {__base_destruct_at_end(this->__begin_);} - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __base_destruct_at_end(pointer __new_last) _NOEXCEPT { - pointer __soon_to_be_end = this->__end_; - while (__new_last != __soon_to_be_end) - __alloc_traits::destroy(__alloc(), std::__to_address(--__soon_to_be_end)); - this->__end_ = __new_last; - } - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __copy_assign_alloc(const vector& __c) - {__copy_assign_alloc(__c, integral_constant());} - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __move_assign_alloc(vector& __c) - _NOEXCEPT_( - !__alloc_traits::propagate_on_container_move_assignment::value || - is_nothrow_move_assignable::value) - {__move_assign_alloc(__c, integral_constant());} - - _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI - void __throw_length_error() const { - std::__throw_length_error("vector"); - } - - _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI - void __throw_out_of_range() const { - std::__throw_out_of_range("vector"); - } - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __copy_assign_alloc(const vector& __c, true_type) - { - if (__alloc() != __c.__alloc()) - { - __clear(); - __alloc_traits::deallocate(__alloc(), this->__begin_, capacity()); - this->__begin_ = this->__end_ = __end_cap() = nullptr; - } - __alloc() = __c.__alloc(); - } - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __copy_assign_alloc(const vector&, false_type) - {} - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __move_assign_alloc(vector& __c, true_type) - _NOEXCEPT_(is_nothrow_move_assignable::value) - { - __alloc() = std::move(__c.__alloc()); - } - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI - void __move_assign_alloc(vector&, false_type) - _NOEXCEPT - {} -}; - -#if _LIBCPP_STD_VER >= 17 -template>, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t<__is_allocator<_Alloc>::value> - > -vector(_InputIterator, _InputIterator) - -> vector<__iter_value_type<_InputIterator>, _Alloc>; - -template::value>, - class = enable_if_t<__is_allocator<_Alloc>::value> - > -vector(_InputIterator, _InputIterator, _Alloc) - -> vector<__iter_value_type<_InputIterator>, _Alloc>; -#endif - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v) -{ - __annotate_delete(); - using _RevIter = std::reverse_iterator; - __v.__begin_ = std::__uninitialized_allocator_move_if_noexcept( - __alloc(), _RevIter(__end_), _RevIter(__begin_), _RevIter(__v.__begin_)) - .base(); - std::swap(this->__begin_, __v.__begin_); - std::swap(this->__end_, __v.__end_); - std::swap(this->__end_cap(), __v.__end_cap()); - __v.__first_ = __v.__begin_; - __annotate_new(size()); - std::__debug_db_invalidate_all(this); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename vector<_Tp, _Allocator>::pointer -vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer& __v, pointer __p) -{ - __annotate_delete(); - pointer __r = __v.__begin_; - using _RevIter = std::reverse_iterator; - __v.__begin_ = std::__uninitialized_allocator_move_if_noexcept( - __alloc(), _RevIter(__p), _RevIter(__begin_), _RevIter(__v.__begin_)) - .base(); - __v.__end_ = std::__uninitialized_allocator_move_if_noexcept(__alloc(), __p, __end_, __v.__end_); - std::swap(this->__begin_, __v.__begin_); - std::swap(this->__end_, __v.__end_); - std::swap(this->__end_cap(), __v.__end_cap()); - __v.__first_ = __v.__begin_; - __annotate_new(size()); - std::__debug_db_invalidate_all(this); - return __r; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::__vdeallocate() _NOEXCEPT -{ - if (this->__begin_ != nullptr) - { - clear(); - __alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity()); - this->__begin_ = this->__end_ = this->__end_cap() = nullptr; - } -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename vector<_Tp, _Allocator>::size_type -vector<_Tp, _Allocator>::max_size() const _NOEXCEPT -{ - return std::min(__alloc_traits::max_size(this->__alloc()), - numeric_limits::max()); -} - -// Precondition: __new_size > capacity() -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -typename vector<_Tp, _Allocator>::size_type -vector<_Tp, _Allocator>::__recommend(size_type __new_size) const -{ - const size_type __ms = max_size(); - if (__new_size > __ms) - this->__throw_length_error(); - const size_type __cap = capacity(); - if (__cap >= __ms / 2) - return __ms; - return std::max(2 * __cap, __new_size); -} - -// Default constructs __n objects starting at __end_ -// throws if construction throws -// Precondition: __n > 0 -// Precondition: size() + __n <= capacity() -// Postcondition: size() == size() + __n -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::__construct_at_end(size_type __n) -{ - _ConstructTransaction __tx(*this, __n); - const_pointer __new_end = __tx.__new_end_; - for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) { - __alloc_traits::construct(this->__alloc(), std::__to_address(__pos)); - } -} - -// Copy constructs __n objects starting at __end_ from __x -// throws if construction throws -// Precondition: __n > 0 -// Precondition: size() + __n <= capacity() -// Postcondition: size() == old size() + __n -// Postcondition: [i] == __x for all i in [size() - __n, __n) -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline -void -vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) -{ - _ConstructTransaction __tx(*this, __n); - const_pointer __new_end = __tx.__new_end_; - for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) { - __alloc_traits::construct(this->__alloc(), std::__to_address(__pos), __x); - } -} - -template -template ::value, int> > -_LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n) -{ - _ConstructTransaction __tx(*this, __n); - __tx.__pos_ = std::__uninitialized_allocator_copy(__alloc(), __first, __last, __tx.__pos_); -} - -// Default constructs __n objects starting at __end_ -// throws if construction throws -// Postcondition: size() == size() + __n -// Exception safety: strong. -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::__append(size_type __n) -{ - if (static_cast(this->__end_cap() - this->__end_) >= __n) - this->__construct_at_end(__n); - else - { - allocator_type& __a = this->__alloc(); - __split_buffer __v(__recommend(size() + __n), size(), __a); - __v.__construct_at_end(__n); - __swap_out_circular_buffer(__v); - } -} - -// Default constructs __n objects starting at __end_ -// throws if construction throws -// Postcondition: size() == size() + __n -// Exception safety: strong. -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::__append(size_type __n, const_reference __x) -{ - if (static_cast(this->__end_cap() - this->__end_) >= __n) - this->__construct_at_end(__n, __x); - else - { - allocator_type& __a = this->__alloc(); - __split_buffer __v(__recommend(size() + __n), size(), __a); - __v.__construct_at_end(__n, __x); - __swap_out_circular_buffer(__v); - } -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector<_Tp, _Allocator>::vector(size_type __n) -{ - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - std::__debug_db_insert_c(this); - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__n); - } - __guard.__complete(); -} - -#if _LIBCPP_STD_VER > 11 -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a) - : __end_cap_(nullptr, __a) -{ - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - std::__debug_db_insert_c(this); - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__n); - } - __guard.__complete(); -} -#endif - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x) -{ - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - std::__debug_db_insert_c(this); - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__n, __x); - } - __guard.__complete(); -} - -template -template ::value && - is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value, - int> > -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last) -{ - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - std::__debug_db_insert_c(this); - for (; __first != __last; ++__first) - emplace_back(*__first); - __guard.__complete(); -} - -template -template ::value && - is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value, - int> > -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a) - : __end_cap_(nullptr, __a) -{ - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - std::__debug_db_insert_c(this); - for (; __first != __last; ++__first) - emplace_back(*__first); - __guard.__complete(); -} - template template ::value && is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value, @@ -4515,1314 +2762,8 @@ vector<_Tp, _Allocator>::vector(initializer_list __il) __guard.__complete(); } -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -vector<_Tp, _Allocator>::vector(initializer_list __il, const allocator_type& __a) - : __end_cap_(nullptr, __a) -{ - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - std::__debug_db_insert_c(this); - if (__il.size() > 0) - { - __vallocate(__il.size()); - __construct_at_end(__il.begin(), __il.end(), __il.size()); - } - __guard.__complete(); -} - -#endif // _LIBCPP_CXX03_LANG - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -vector<_Tp, _Allocator>& -vector<_Tp, _Allocator>::operator=(vector&& __x) - _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) -{ - __move_assign(__x, integral_constant()); - return *this; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::__move_assign(vector& __c, false_type) - _NOEXCEPT_(__alloc_traits::is_always_equal::value) -{ - if (__alloc() != __c.__alloc()) - { - typedef move_iterator _Ip; - assign(_Ip(__c.begin()), _Ip(__c.end())); - } - else - __move_assign(__c, true_type()); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type) - _NOEXCEPT_(is_nothrow_move_assignable::value) -{ - __vdeallocate(); - __move_assign_alloc(__c); // this can throw - this->__begin_ = __c.__begin_; - this->__end_ = __c.__end_; - this->__end_cap() = __c.__end_cap(); - __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr; - std::__debug_db_swap(this, std::addressof(__c)); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -vector<_Tp, _Allocator>& -vector<_Tp, _Allocator>::operator=(const vector& __x) -{ - if (this != std::addressof(__x)) - { - __copy_assign_alloc(__x); - assign(__x.__begin_, __x.__end_); - } - return *this; -} - -template -template ::value && - is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value, - int> > -_LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector<_Tp, _Allocator>::assign(_InputIterator __first, _InputIterator __last) -{ - clear(); - for (; __first != __last; ++__first) - emplace_back(*__first); -} - -template -template ::value && - is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value, - int> > -_LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) -{ - size_type __new_size = static_cast(std::distance(__first, __last)); - if (__new_size <= capacity()) - { - _ForwardIterator __mid = __last; - bool __growing = false; - if (__new_size > size()) - { - __growing = true; - __mid = __first; - std::advance(__mid, size()); - } - pointer __m = std::copy(__first, __mid, this->__begin_); - if (__growing) - __construct_at_end(__mid, __last, __new_size - size()); - else - this->__destruct_at_end(__m); - } - else - { - __vdeallocate(); - __vallocate(__recommend(__new_size)); - __construct_at_end(__first, __last, __new_size); - } - std::__debug_db_invalidate_all(this); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u) -{ - if (__n <= capacity()) - { - size_type __s = size(); - std::fill_n(this->__begin_, std::min(__n, __s), __u); - if (__n > __s) - __construct_at_end(__n - __s, __u); - else - this->__destruct_at_end(this->__begin_ + __n); - } - else - { - __vdeallocate(); - __vallocate(__recommend(static_cast(__n))); - __construct_at_end(__n, __u); - } - std::__debug_db_invalidate_all(this); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -typename vector<_Tp, _Allocator>::iterator -vector<_Tp, _Allocator>::begin() _NOEXCEPT -{ - return __make_iter(this->__begin_); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -typename vector<_Tp, _Allocator>::const_iterator -vector<_Tp, _Allocator>::begin() const _NOEXCEPT -{ - return __make_iter(this->__begin_); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -typename vector<_Tp, _Allocator>::iterator -vector<_Tp, _Allocator>::end() _NOEXCEPT -{ - return __make_iter(this->__end_); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -typename vector<_Tp, _Allocator>::const_iterator -vector<_Tp, _Allocator>::end() const _NOEXCEPT -{ - return __make_iter(this->__end_); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -typename vector<_Tp, _Allocator>::reference -vector<_Tp, _Allocator>::operator[](size_type __n) _NOEXCEPT -{ - _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds"); - return this->__begin_[__n]; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -typename vector<_Tp, _Allocator>::const_reference -vector<_Tp, _Allocator>::operator[](size_type __n) const _NOEXCEPT -{ - _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds"); - return this->__begin_[__n]; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename vector<_Tp, _Allocator>::reference -vector<_Tp, _Allocator>::at(size_type __n) -{ - if (__n >= size()) - this->__throw_out_of_range(); - return this->__begin_[__n]; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename vector<_Tp, _Allocator>::const_reference -vector<_Tp, _Allocator>::at(size_type __n) const -{ - if (__n >= size()) - this->__throw_out_of_range(); - return this->__begin_[__n]; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::reserve(size_type __n) -{ - if (__n > capacity()) - { - if (__n > max_size()) - this->__throw_length_error(); - allocator_type& __a = this->__alloc(); - __split_buffer __v(__n, size(), __a); - __swap_out_circular_buffer(__v); - } -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT -{ - if (capacity() > size()) - { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - allocator_type& __a = this->__alloc(); - __split_buffer __v(size(), size(), __a); - __swap_out_circular_buffer(__v); -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - } -#endif // _LIBCPP_NO_EXCEPTIONS - } -} - -template -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::__push_back_slow_path(_Up&& __x) -{ - allocator_type& __a = this->__alloc(); - __split_buffer __v(__recommend(size() + 1), size(), __a); - // __v.push_back(std::forward<_Up>(__x)); - __alloc_traits::construct(__a, std::__to_address(__v.__end_), std::forward<_Up>(__x)); - __v.__end_++; - __swap_out_circular_buffer(__v); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -void -vector<_Tp, _Allocator>::push_back(const_reference __x) -{ - if (this->__end_ != this->__end_cap()) - { - __construct_one_at_end(__x); - } - else - __push_back_slow_path(__x); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -void -vector<_Tp, _Allocator>::push_back(value_type&& __x) -{ - if (this->__end_ < this->__end_cap()) - { - __construct_one_at_end(std::move(__x)); - } - else - __push_back_slow_path(std::move(__x)); -} - -template -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args) -{ - allocator_type& __a = this->__alloc(); - __split_buffer __v(__recommend(size() + 1), size(), __a); -// __v.emplace_back(std::forward<_Args>(__args)...); - __alloc_traits::construct(__a, std::__to_address(__v.__end_), std::forward<_Args>(__args)...); - __v.__end_++; - __swap_out_circular_buffer(__v); -} - -template -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline -#if _LIBCPP_STD_VER > 14 -typename vector<_Tp, _Allocator>::reference -#else -void -#endif -vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) -{ - if (this->__end_ < this->__end_cap()) - { - __construct_one_at_end(std::forward<_Args>(__args)...); - } - else - __emplace_back_slow_path(std::forward<_Args>(__args)...); -#if _LIBCPP_STD_VER > 14 - return this->back(); -#endif -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline -void -vector<_Tp, _Allocator>::pop_back() -{ - _LIBCPP_ASSERT(!empty(), "vector::pop_back called on an empty vector"); - this->__destruct_at_end(this->__end_ - 1); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -typename vector<_Tp, _Allocator>::iterator -vector<_Tp, _Allocator>::erase(const_iterator __position) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, - "vector::erase(iterator) called with an iterator not referring to this vector"); - _LIBCPP_ASSERT(__position != end(), - "vector::erase(iterator) called with a non-dereferenceable iterator"); - difference_type __ps = __position - cbegin(); - pointer __p = this->__begin_ + __ps; - this->__destruct_at_end(std::move(__p + 1, this->__end_, __p)); - if (!__libcpp_is_constant_evaluated()) - this->__invalidate_iterators_past(__p - 1); - return __make_iter(__p); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename vector<_Tp, _Allocator>::iterator -vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__first)) == this, - "vector::erase(iterator, iterator) called with an iterator not referring to this vector"); - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__last)) == this, - "vector::erase(iterator, iterator) called with an iterator not referring to this vector"); - - _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range"); - pointer __p = this->__begin_ + (__first - begin()); - if (__first != __last) { - this->__destruct_at_end(std::move(__p + (__last - __first), this->__end_, __p)); - if (!__libcpp_is_constant_evaluated()) - this->__invalidate_iterators_past(__p - 1); - } - return __make_iter(__p); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointer __to) -{ - pointer __old_last = this->__end_; - difference_type __n = __old_last - __to; - { - pointer __i = __from_s + __n; - _ConstructTransaction __tx(*this, __from_e - __i); - for (pointer __pos = __tx.__pos_; __i < __from_e; - ++__i, (void) ++__pos, __tx.__pos_ = __pos) { - __alloc_traits::construct(this->__alloc(), - std::__to_address(__pos), - std::move(*__i)); - } - } - std::move_backward(__from_s, __from_s + __n, __old_last); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename vector<_Tp, _Allocator>::iterator -vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, - "vector::insert(iterator, x) called with an iterator not referring to this vector"); - pointer __p = this->__begin_ + (__position - begin()); - // We can't compare unrelated pointers inside constant expressions - if (!__libcpp_is_constant_evaluated() && this->__end_ < this->__end_cap()) - { - if (__p == this->__end_) - { - __construct_one_at_end(__x); - } - else - { - __move_range(__p, this->__end_, __p + 1); - const_pointer __xr = pointer_traits::pointer_to(__x); - if (__p <= __xr && __xr < this->__end_) - ++__xr; - *__p = *__xr; - } - } - else - { - allocator_type& __a = this->__alloc(); - __split_buffer __v(__recommend(size() + 1), __p - this->__begin_, __a); - __v.push_back(__x); - __p = __swap_out_circular_buffer(__v, __p); - } - return __make_iter(__p); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename vector<_Tp, _Allocator>::iterator -vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, - "vector::insert(iterator, x) called with an iterator not referring to this vector"); - pointer __p = this->__begin_ + (__position - begin()); - if (this->__end_ < this->__end_cap()) - { - if (__p == this->__end_) - { - __construct_one_at_end(std::move(__x)); - } - else - { - __move_range(__p, this->__end_, __p + 1); - *__p = std::move(__x); - } - } - else - { - allocator_type& __a = this->__alloc(); - __split_buffer __v(__recommend(size() + 1), __p - this->__begin_, __a); - __v.push_back(std::move(__x)); - __p = __swap_out_circular_buffer(__v, __p); - } - return __make_iter(__p); -} - -template -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename vector<_Tp, _Allocator>::iterator -vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, - "vector::emplace(iterator, x) called with an iterator not referring to this vector"); - pointer __p = this->__begin_ + (__position - begin()); - if (this->__end_ < this->__end_cap()) - { - if (__p == this->__end_) - { - __construct_one_at_end(std::forward<_Args>(__args)...); - } - else - { - __temp_value __tmp(this->__alloc(), std::forward<_Args>(__args)...); - __move_range(__p, this->__end_, __p + 1); - *__p = std::move(__tmp.get()); - } - } - else - { - allocator_type& __a = this->__alloc(); - __split_buffer __v(__recommend(size() + 1), __p - this->__begin_, __a); - __v.emplace_back(std::forward<_Args>(__args)...); - __p = __swap_out_circular_buffer(__v, __p); - } - return __make_iter(__p); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename vector<_Tp, _Allocator>::iterator -vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, - "vector::insert(iterator, n, x) called with an iterator not referring to this vector"); - pointer __p = this->__begin_ + (__position - begin()); - if (__n > 0) - { - // We can't compare unrelated pointers inside constant expressions - if (!__libcpp_is_constant_evaluated() && __n <= static_cast(this->__end_cap() - this->__end_)) - { - size_type __old_n = __n; - pointer __old_last = this->__end_; - if (__n > static_cast(this->__end_ - __p)) - { - size_type __cx = __n - (this->__end_ - __p); - __construct_at_end(__cx, __x); - __n -= __cx; - } - if (__n > 0) - { - __move_range(__p, __old_last, __p + __old_n); - const_pointer __xr = pointer_traits::pointer_to(__x); - if (__p <= __xr && __xr < this->__end_) - __xr += __old_n; - std::fill_n(__p, __n, *__xr); - } - } - else - { - allocator_type& __a = this->__alloc(); - __split_buffer __v(__recommend(size() + __n), __p - this->__begin_, __a); - __v.__construct_at_end(__n, __x); - __p = __swap_out_circular_buffer(__v, __p); - } - } - return __make_iter(__p); -} - -template -template ::value && - is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value, - int> > -_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator -vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, - "vector::insert(iterator, range) called with an iterator not referring to this vector"); - difference_type __off = __position - begin(); - pointer __p = this->__begin_ + __off; - allocator_type& __a = this->__alloc(); - pointer __old_last = this->__end_; - for (; this->__end_ != this->__end_cap() && __first != __last; ++__first) - { - __construct_one_at_end(*__first); - } - __split_buffer __v(__a); - if (__first != __last) - { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - __v.__construct_at_end(__first, __last); - difference_type __old_size = __old_last - this->__begin_; - difference_type __old_p = __p - this->__begin_; - reserve(__recommend(size() + __v.size())); - __p = this->__begin_ + __old_p; - __old_last = this->__begin_ + __old_size; -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - erase(__make_iter(__old_last), end()); - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS - } - __p = std::rotate(__p, __old_last, this->__end_); - insert(__make_iter(__p), std::make_move_iterator(__v.begin()), - std::make_move_iterator(__v.end())); - return begin() + __off; -} - -template -template ::value && - is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value, - int> > -_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator -vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, - "vector::insert(iterator, range) called with an iterator not referring to this vector"); - pointer __p = this->__begin_ + (__position - begin()); - difference_type __n = std::distance(__first, __last); - if (__n > 0) - { - if (__n <= this->__end_cap() - this->__end_) - { - size_type __old_n = __n; - pointer __old_last = this->__end_; - _ForwardIterator __m = __last; - difference_type __dx = this->__end_ - __p; - if (__n > __dx) - { - __m = __first; - difference_type __diff = this->__end_ - __p; - std::advance(__m, __diff); - __construct_at_end(__m, __last, __n - __diff); - __n = __dx; - } - if (__n > 0) - { - __move_range(__p, __old_last, __p + __old_n); - std::copy(__first, __m, __p); - } - } - else - { - allocator_type& __a = this->__alloc(); - __split_buffer __v(__recommend(size() + __n), __p - this->__begin_, __a); - __v.__construct_at_end(__first, __last); - __p = __swap_out_circular_buffer(__v, __p); - } - } - return __make_iter(__p); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::resize(size_type __sz) -{ - size_type __cs = size(); - if (__cs < __sz) - this->__append(__sz - __cs); - else if (__cs > __sz) - this->__destruct_at_end(this->__begin_ + __sz); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::resize(size_type __sz, const_reference __x) -{ - size_type __cs = size(); - if (__cs < __sz) - this->__append(__sz - __cs, __x); - else if (__cs > __sz) - this->__destruct_at_end(this->__begin_ + __sz); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector<_Tp, _Allocator>::swap(vector& __x) -#if _LIBCPP_STD_VER >= 14 - _NOEXCEPT -#else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || - __is_nothrow_swappable::value) -#endif -{ - _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value || - this->__alloc() == __x.__alloc(), - "vector::swap: Either propagate_on_container_swap must be true" - " or the allocators must compare equal"); - std::swap(this->__begin_, __x.__begin_); - std::swap(this->__end_, __x.__end_); - std::swap(this->__end_cap(), __x.__end_cap()); - std::__swap_allocator(this->__alloc(), __x.__alloc(), - integral_constant()); - std::__debug_db_swap(this, std::addressof(__x)); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -vector<_Tp, _Allocator>::__invariants() const -{ - if (this->__begin_ == nullptr) - { - if (this->__end_ != nullptr || this->__end_cap() != nullptr) - return false; - } - else - { - if (this->__begin_ > this->__end_) - return false; - if (this->__begin_ == this->__end_cap()) - return false; - if (this->__end_ > this->__end_cap()) - return false; - } - return true; -} - -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - -template -bool -vector<_Tp, _Allocator>::__dereferenceable(const const_iterator* __i) const -{ - return this->__begin_ <= __i->base() && __i->base() < this->__end_; -} - -template -bool -vector<_Tp, _Allocator>::__decrementable(const const_iterator* __i) const -{ - return this->__begin_ < __i->base() && __i->base() <= this->__end_; -} - -template -bool -vector<_Tp, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const -{ - const_pointer __p = __i->base() + __n; - return this->__begin_ <= __p && __p <= this->__end_; -} - -template -bool -vector<_Tp, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const -{ - const_pointer __p = __i->base() + __n; - return this->__begin_ <= __p && __p < this->__end_; -} - -#endif // _LIBCPP_ENABLE_DEBUG_MODE - -template -inline _LIBCPP_HIDE_FROM_ABI -void -vector<_Tp, _Allocator>::__invalidate_iterators_past(pointer __new_last) { -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - __c_node* __c = __get_db()->__find_c_and_lock(this); - for (__i_node** __p = __c->end_; __p != __c->beg_; ) { - --__p; - const_iterator* __i = static_cast((*__p)->__i_); - if (__i->base() > __new_last) { - (*__p)->__c_ = nullptr; - if (--__c->end_ != __p) - std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); - } - } - __get_db()->unlock(); -#else - ((void)__new_last); -#endif -} - // vector -template class vector; - -template struct hash >; - -template -struct __has_storage_type > -{ - static const bool value = true; -}; - -template -class _LIBCPP_TEMPLATE_VIS vector -{ -public: - typedef vector __self; - typedef bool value_type; - typedef _Allocator allocator_type; - typedef allocator_traits __alloc_traits; - typedef typename __alloc_traits::size_type size_type; - typedef typename __alloc_traits::difference_type difference_type; - typedef size_type __storage_type; - typedef __bit_iterator pointer; - typedef __bit_iterator const_pointer; - typedef pointer iterator; - typedef const_pointer const_iterator; - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - -private: - typedef __rebind_alloc<__alloc_traits, __storage_type> __storage_allocator; - typedef allocator_traits<__storage_allocator> __storage_traits; - typedef typename __storage_traits::pointer __storage_pointer; - typedef typename __storage_traits::const_pointer __const_storage_pointer; - - __storage_pointer __begin_; - size_type __size_; - __compressed_pair __cap_alloc_; -public: - typedef __bit_reference reference; -#ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL - using const_reference = bool; -#else - typedef __bit_const_reference const_reference; -#endif -private: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - size_type& __cap() _NOEXCEPT - {return __cap_alloc_.first();} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - const size_type& __cap() const _NOEXCEPT - {return __cap_alloc_.first();} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - __storage_allocator& __alloc() _NOEXCEPT - {return __cap_alloc_.second();} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - const __storage_allocator& __alloc() const _NOEXCEPT - {return __cap_alloc_.second();} - - static const unsigned __bits_per_word = static_cast(sizeof(__storage_type) * CHAR_BIT); - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - static size_type __internal_cap_to_external(size_type __n) _NOEXCEPT - {return __n * __bits_per_word;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - static size_type __external_cap_to_internal(size_type __n) _NOEXCEPT - {return (__n - 1) / __bits_per_word + 1;} - -public: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - vector() _NOEXCEPT_(is_nothrow_default_constructible::value); - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(const allocator_type& __a) -#if _LIBCPP_STD_VER <= 14 - _NOEXCEPT_(is_nothrow_copy_constructible::value); -#else - _NOEXCEPT; -#endif - -private: - class __destroy_vector { - public: - _LIBCPP_CONSTEXPR __destroy_vector(vector& __vec) : __vec_(__vec) {} - - _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator()() { - if (__vec_.__begin_ != nullptr) - __storage_traits::deallocate(__vec_.__alloc(), __vec_.__begin_, __vec_.__cap()); - std::__debug_db_invalidate_all(this); - } - - private: - vector& __vec_; - }; - -public: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~vector() { __destroy_vector(*this)(); } - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n); -#if _LIBCPP_STD_VER > 11 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n, const allocator_type& __a); -#endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(size_type __n, const value_type& __v); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(size_type __n, const value_type& __v, const allocator_type& __a); - template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_InputIterator __first, _InputIterator __last, - typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type* = 0); - template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a, - typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type* = 0); - template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_ForwardIterator __first, _ForwardIterator __last, - typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0); - template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a, - typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0); - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(const vector& __v); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(const vector& __v, const allocator_type& __a); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector& operator=(const vector& __v); - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(initializer_list __il); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(initializer_list __il, const allocator_type& __a); - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - vector& operator=(initializer_list __il) - {assign(__il.begin(), __il.end()); return *this;} - -#endif // !_LIBCPP_CXX03_LANG - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - vector(vector&& __v) -#if _LIBCPP_STD_VER > 14 - noexcept; -#else - _NOEXCEPT_(is_nothrow_move_constructible::value); -#endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(vector&& __v, const __type_identity_t& __a); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - vector& operator=(vector&& __v) - _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)); - - template - typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value, - void - >::type - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 assign(_InputIterator __first, _InputIterator __last); - template - typename enable_if - < - __is_cpp17_forward_iterator<_ForwardIterator>::value, - void - >::type - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 assign(_ForwardIterator __first, _ForwardIterator __last); - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void assign(size_type __n, const value_type& __x); - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - void assign(initializer_list __il) - {assign(__il.begin(), __il.end());} -#endif - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator_type get_allocator() const _NOEXCEPT - {return allocator_type(this->__alloc());} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type max_size() const _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - size_type capacity() const _NOEXCEPT - {return __internal_cap_to_external(__cap());} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - size_type size() const _NOEXCEPT - {return __size_;} - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - bool empty() const _NOEXCEPT - {return __size_ == 0;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reserve(size_type __n); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void shrink_to_fit() _NOEXCEPT; - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - iterator begin() _NOEXCEPT - {return __make_iter(0);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - const_iterator begin() const _NOEXCEPT - {return __make_iter(0);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - iterator end() _NOEXCEPT - {return __make_iter(__size_);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - const_iterator end() const _NOEXCEPT - {return __make_iter(__size_);} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - reverse_iterator rbegin() _NOEXCEPT - {return reverse_iterator(end());} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - const_reverse_iterator rbegin() const _NOEXCEPT - {return const_reverse_iterator(end());} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - reverse_iterator rend() _NOEXCEPT - {return reverse_iterator(begin());} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - const_reverse_iterator rend() const _NOEXCEPT - {return const_reverse_iterator(begin());} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - const_iterator cbegin() const _NOEXCEPT - {return __make_iter(0);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - const_iterator cend() const _NOEXCEPT - {return __make_iter(__size_);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - const_reverse_iterator crbegin() const _NOEXCEPT - {return rbegin();} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - const_reverse_iterator crend() const _NOEXCEPT - {return rend();} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __n) {return __make_ref(__n);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __n) const {return __make_ref(__n);} - _LIBCPP_HIDE_FROM_ABI reference at(size_type __n); - _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __n) const; - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() {return __make_ref(0);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const {return __make_ref(0);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() {return __make_ref(__size_ - 1);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const {return __make_ref(__size_ - 1);} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(const value_type& __x); -#if _LIBCPP_STD_VER > 11 - template -#if _LIBCPP_STD_VER > 14 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference emplace_back(_Args&&... __args) -#else - _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args) -#endif - { - push_back ( value_type ( std::forward<_Args>(__args)... )); -#if _LIBCPP_STD_VER > 14 - return this->back(); -#endif - } -#endif - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back() {--__size_;} - -#if _LIBCPP_STD_VER > 11 - template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator emplace(const_iterator __position, _Args&&... __args) - { return insert ( __position, value_type ( std::forward<_Args>(__args)... )); } -#endif - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __position, const value_type& __x); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __position, size_type __n, const value_type& __x); - template - typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value, - iterator - >::type - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert(const_iterator __position, _InputIterator __first, _InputIterator __last); - template - typename enable_if - < - __is_cpp17_forward_iterator<_ForwardIterator>::value, - iterator - >::type - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last); - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - iterator insert(const_iterator __position, initializer_list __il) - {return insert(__position, __il.begin(), __il.end());} -#endif - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator erase(const_iterator __position); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator erase(const_iterator __first, const_iterator __last); - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - void clear() _NOEXCEPT {__size_ = 0;} - - _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(vector&) -#if _LIBCPP_STD_VER >= 14 - _NOEXCEPT; -#else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || - __is_nothrow_swappable::value); -#endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void swap(reference __x, reference __y) _NOEXCEPT { std::swap(__x, __y); } - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __sz, value_type __x = false); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT; - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __invariants() const; - -private: - _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI - void __throw_length_error() const { - std::__throw_length_error("vector"); - } - - _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI - void __throw_out_of_range() const { - std::__throw_out_of_range("vector"); - } - - // Allocate space for __n objects - // throws length_error if __n > max_size() - // throws (probably bad_alloc) if memory run out - // Precondition: __begin_ == __end_ == __cap() == 0 - // Precondition: __n > 0 - // Postcondition: capacity() >= __n - // Postcondition: size() == 0 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __vallocate(size_type __n) { - if (__n > max_size()) - __throw_length_error(); - auto __allocation = std::__allocate_at_least(__alloc(), __external_cap_to_internal(__n)); - __begin_ = __allocation.ptr; - __size_ = 0; - __cap() = __allocation.count; - if (__libcpp_is_constant_evaluated()) { - for (size_type __i = 0; __i != __cap(); ++__i) - std::__construct_at(std::__to_address(__begin_) + __i); - } - } - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __vdeallocate() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - static size_type __align_it(size_type __new_size) _NOEXCEPT - {return (__new_size + (__bits_per_word-1)) & ~((size_type)__bits_per_word-1);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __new_size) const; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_at_end(size_type __n, bool __x); - template - typename enable_if - < - __is_cpp17_forward_iterator<_ForwardIterator>::value, - void - >::type - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __construct_at_end(_ForwardIterator __first, _ForwardIterator __last); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __append(size_type __n, const_reference __x); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - reference __make_ref(size_type __pos) _NOEXCEPT - {return reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - const_reference __make_ref(size_type __pos) const _NOEXCEPT { - return __bit_const_reference(__begin_ + __pos / __bits_per_word, - __storage_type(1) << __pos % __bits_per_word); - } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - iterator __make_iter(size_type __pos) _NOEXCEPT - {return iterator(__begin_ + __pos / __bits_per_word, static_cast(__pos % __bits_per_word));} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - const_iterator __make_iter(size_type __pos) const _NOEXCEPT - {return const_iterator(__begin_ + __pos / __bits_per_word, static_cast(__pos % __bits_per_word));} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - iterator __const_iterator_cast(const_iterator __p) _NOEXCEPT - {return begin() + (__p - cbegin());} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - void __copy_assign_alloc(const vector& __v) - {__copy_assign_alloc(__v, integral_constant());} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - void __copy_assign_alloc(const vector& __c, true_type) - { - if (__alloc() != __c.__alloc()) - __vdeallocate(); - __alloc() = __c.__alloc(); - } - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - void __copy_assign_alloc(const vector&, false_type) - {} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign(vector& __c, false_type); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __move_assign(vector& __c, true_type) - _NOEXCEPT_(is_nothrow_move_assignable::value); - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - void __move_assign_alloc(vector& __c) - _NOEXCEPT_( - !__storage_traits::propagate_on_container_move_assignment::value || - is_nothrow_move_assignable::value) - {__move_assign_alloc(__c, integral_constant());} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - void __move_assign_alloc(vector& __c, true_type) - _NOEXCEPT_(is_nothrow_move_assignable::value) - { - __alloc() = std::move(__c.__alloc()); - } - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - void __move_assign_alloc(vector&, false_type) - _NOEXCEPT - {} - - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_t __hash_code() const _NOEXCEPT; - - friend class __bit_reference; - friend class __bit_const_reference; - friend class __bit_iterator; - friend class __bit_iterator; - friend struct __bit_array; - friend struct _LIBCPP_TEMPLATE_VIS hash; -}; - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector::__vdeallocate() _NOEXCEPT -{ - if (this->__begin_ != nullptr) - { - __storage_traits::deallocate(this->__alloc(), this->__begin_, __cap()); - std::__debug_db_invalidate_all(this); - this->__begin_ = nullptr; - this->__size_ = this->__cap() = 0; - } -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename vector::size_type -vector::max_size() const _NOEXCEPT -{ - size_type __amax = __storage_traits::max_size(__alloc()); - size_type __nmax = numeric_limits::max() / 2; // end() >= begin(), always - if (__nmax / __bits_per_word <= __amax) - return __nmax; - return __internal_cap_to_external(__amax); -} - -// Precondition: __new_size > capacity() -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename vector::size_type -vector::__recommend(size_type __new_size) const -{ - const size_type __ms = max_size(); - if (__new_size > __ms) - this->__throw_length_error(); - const size_type __cap = capacity(); - if (__cap >= __ms / 2) - return __ms; - return std::max(2 * __cap, __align_it(__new_size)); -} - -// Default constructs __n objects starting at __end_ -// Precondition: __n > 0 -// Precondition: size() + __n <= capacity() -// Postcondition: size() == size() + __n -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -vector::__construct_at_end(size_type __n, bool __x) -{ - size_type __old_size = this->__size_; - this->__size_ += __n; - if (__old_size == 0 || ((__old_size - 1) / __bits_per_word) != ((this->__size_ - 1) / __bits_per_word)) - { - if (this->__size_ <= __bits_per_word) - this->__begin_[0] = __storage_type(0); - else - this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0); - } - std::fill_n(__make_iter(__old_size), __n, __x); -} - -template -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename enable_if -< - __is_cpp17_forward_iterator<_ForwardIterator>::value, - void ->::type -vector::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) -{ - size_type __old_size = this->__size_; - this->__size_ += std::distance(__first, __last); - if (__old_size == 0 || ((__old_size - 1) / __bits_per_word) != ((this->__size_ - 1) / __bits_per_word)) - { - if (this->__size_ <= __bits_per_word) - this->__begin_[0] = __storage_type(0); - else - this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0); - } - std::copy(__first, __last, __make_iter(__old_size)); -} - -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector() - _NOEXCEPT_(is_nothrow_default_constructible::value) - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, __default_init_tag()) -{ -} - -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector(const allocator_type& __a) -#if _LIBCPP_STD_VER <= 14 - _NOEXCEPT_(is_nothrow_copy_constructible::value) -#else - _NOEXCEPT -#endif - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, static_cast<__storage_allocator>(__a)) -{ -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector(size_type __n) - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, __default_init_tag()) -{ - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__n, false); - } -} - -#if _LIBCPP_STD_VER > 11 -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector(size_type __n, const allocator_type& __a) - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, static_cast<__storage_allocator>(__a)) -{ - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__n, false); - } -} -#endif - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector(size_type __n, const value_type& __x) - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, __default_init_tag()) -{ - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__n, __x); - } -} - template _LIBCPP_CONSTEXPR_SINCE_CXX20 vector::vector(size_type __n, const value_type& __x, const allocator_type& __a) @@ -5836,1333 +2777,6 @@ vector::vector(size_type __n, const value_type& __x, const all __construct_at_end(__n, __x); } } - -template -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector(_InputIterator __first, _InputIterator __last, - typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type*) - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, __default_init_tag()) -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - for (; __first != __last; ++__first) - push_back(*__first); -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - if (__begin_ != nullptr) - __storage_traits::deallocate(__alloc(), __begin_, __cap()); - std::__debug_db_invalidate_all(this); - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS -} - -template -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a, - typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type*) - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, static_cast<__storage_allocator>(__a)) -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - for (; __first != __last; ++__first) - push_back(*__first); -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - if (__begin_ != nullptr) - __storage_traits::deallocate(__alloc(), __begin_, __cap()); - std::__debug_db_invalidate_all(this); - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS -} - -template -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector(_ForwardIterator __first, _ForwardIterator __last, - typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type*) - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, __default_init_tag()) -{ - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - size_type __n = static_cast(std::distance(__first, __last)); - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__first, __last); - } - __guard.__complete(); -} - -template -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a, - typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type*) - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, static_cast<__storage_allocator>(__a)) -{ - auto __guard = std::__make_exception_guard(__destroy_vector(*this)); - size_type __n = static_cast(std::distance(__first, __last)); - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__first, __last); - } - __guard.__complete(); -} - -#ifndef _LIBCPP_CXX03_LANG - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector(initializer_list __il) - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, __default_init_tag()) -{ - size_type __n = static_cast(__il.size()); - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__il.begin(), __il.end()); - } -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector(initializer_list __il, const allocator_type& __a) - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, static_cast<__storage_allocator>(__a)) -{ - size_type __n = static_cast(__il.size()); - if (__n > 0) - { - __vallocate(__n); - __construct_at_end(__il.begin(), __il.end()); - } -} - -#endif // _LIBCPP_CXX03_LANG - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector(const vector& __v) - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, __storage_traits::select_on_container_copy_construction(__v.__alloc())) -{ - if (__v.size() > 0) - { - __vallocate(__v.size()); - __construct_at_end(__v.begin(), __v.end()); - } -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector(const vector& __v, const allocator_type& __a) - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, __a) -{ - if (__v.size() > 0) - { - __vallocate(__v.size()); - __construct_at_end(__v.begin(), __v.end()); - } -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector& -vector::operator=(const vector& __v) -{ - if (this != std::addressof(__v)) - { - __copy_assign_alloc(__v); - if (__v.__size_) - { - if (__v.__size_ > capacity()) - { - __vdeallocate(); - __vallocate(__v.__size_); - } - std::copy(__v.__begin_, __v.__begin_ + __external_cap_to_internal(__v.__size_), __begin_); - } - __size_ = __v.__size_; - } - return *this; -} - -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector::vector(vector&& __v) -#if _LIBCPP_STD_VER > 14 - _NOEXCEPT -#else - _NOEXCEPT_(is_nothrow_move_constructible::value) -#endif - : __begin_(__v.__begin_), - __size_(__v.__size_), - __cap_alloc_(std::move(__v.__cap_alloc_)) { - __v.__begin_ = nullptr; - __v.__size_ = 0; - __v.__cap() = 0; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -vector::vector(vector&& __v, const __type_identity_t& __a) - : __begin_(nullptr), - __size_(0), - __cap_alloc_(0, __a) -{ - if (__a == allocator_type(__v.__alloc())) - { - this->__begin_ = __v.__begin_; - this->__size_ = __v.__size_; - this->__cap() = __v.__cap(); - __v.__begin_ = nullptr; - __v.__cap() = __v.__size_ = 0; - } - else if (__v.size() > 0) - { - __vallocate(__v.size()); - __construct_at_end(__v.begin(), __v.end()); - } -} - -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -vector& -vector::operator=(vector&& __v) - _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) -{ - __move_assign(__v, integral_constant()); - return *this; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector::__move_assign(vector& __c, false_type) -{ - if (__alloc() != __c.__alloc()) - assign(__c.begin(), __c.end()); - else - __move_assign(__c, true_type()); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector::__move_assign(vector& __c, true_type) - _NOEXCEPT_(is_nothrow_move_assignable::value) -{ - __vdeallocate(); - __move_assign_alloc(__c); - this->__begin_ = __c.__begin_; - this->__size_ = __c.__size_; - this->__cap() = __c.__cap(); - __c.__begin_ = nullptr; - __c.__cap() = __c.__size_ = 0; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector::assign(size_type __n, const value_type& __x) -{ - __size_ = 0; - if (__n > 0) - { - size_type __c = capacity(); - if (__n <= __c) - __size_ = __n; - else - { - vector __v(get_allocator()); - __v.reserve(__recommend(__n)); - __v.__size_ = __n; - swap(__v); - } - std::fill_n(begin(), __n, __x); - } - std::__debug_db_invalidate_all(this); -} - -template -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value, - void ->::type -vector::assign(_InputIterator __first, _InputIterator __last) -{ - clear(); - for (; __first != __last; ++__first) - push_back(*__first); -} - -template -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename enable_if -< - __is_cpp17_forward_iterator<_ForwardIterator>::value, - void ->::type -vector::assign(_ForwardIterator __first, _ForwardIterator __last) -{ - clear(); - difference_type __ns = std::distance(__first, __last); - _LIBCPP_ASSERT(__ns >= 0, "invalid range specified"); - const size_t __n = static_cast(__ns); - if (__n) - { - if (__n > capacity()) - { - __vdeallocate(); - __vallocate(__n); - } - __construct_at_end(__first, __last); - } -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector::reserve(size_type __n) -{ - if (__n > capacity()) - { - if (__n > max_size()) - this->__throw_length_error(); - vector __v(this->get_allocator()); - __v.__vallocate(__n); - __v.__construct_at_end(this->begin(), this->end()); - swap(__v); - std::__debug_db_invalidate_all(this); - } -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector::shrink_to_fit() _NOEXCEPT -{ - if (__external_cap_to_internal(size()) > __cap()) - { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - vector(*this, allocator_type(__alloc())).swap(*this); -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - } -#endif // _LIBCPP_NO_EXCEPTIONS - } -} - -template -typename vector::reference -vector::at(size_type __n) -{ - if (__n >= size()) - this->__throw_out_of_range(); - return (*this)[__n]; -} - -template -typename vector::const_reference -vector::at(size_type __n) const -{ - if (__n >= size()) - this->__throw_out_of_range(); - return (*this)[__n]; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector::push_back(const value_type& __x) -{ - if (this->__size_ == this->capacity()) - reserve(__recommend(this->__size_ + 1)); - ++this->__size_; - back() = __x; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector::iterator -vector::insert(const_iterator __position, const value_type& __x) -{ - iterator __r; - if (size() < capacity()) - { - const_iterator __old_end = end(); - ++__size_; - std::copy_backward(__position, __old_end, end()); - __r = __const_iterator_cast(__position); - } - else - { - vector __v(get_allocator()); - __v.reserve(__recommend(__size_ + 1)); - __v.__size_ = __size_ + 1; - __r = std::copy(cbegin(), __position, __v.begin()); - std::copy_backward(__position, cend(), __v.end()); - swap(__v); - } - *__r = __x; - return __r; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector::iterator -vector::insert(const_iterator __position, size_type __n, const value_type& __x) -{ - iterator __r; - size_type __c = capacity(); - if (__n <= __c && size() <= __c - __n) - { - const_iterator __old_end = end(); - __size_ += __n; - std::copy_backward(__position, __old_end, end()); - __r = __const_iterator_cast(__position); - } - else - { - vector __v(get_allocator()); - __v.reserve(__recommend(__size_ + __n)); - __v.__size_ = __size_ + __n; - __r = std::copy(cbegin(), __position, __v.begin()); - std::copy_backward(__position, cend(), __v.end()); - swap(__v); - } - std::fill_n(__r, __n, __x); - return __r; -} - -template -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value, - typename vector::iterator ->::type -vector::insert(const_iterator __position, _InputIterator __first, _InputIterator __last) -{ - difference_type __off = __position - begin(); - iterator __p = __const_iterator_cast(__position); - iterator __old_end = end(); - for (; size() != capacity() && __first != __last; ++__first) - { - ++this->__size_; - back() = *__first; - } - vector __v(get_allocator()); - if (__first != __last) - { -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - __v.assign(__first, __last); - difference_type __old_size = static_cast(__old_end - begin()); - difference_type __old_p = __p - begin(); - reserve(__recommend(size() + __v.size())); - __p = begin() + __old_p; - __old_end = begin() + __old_size; -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - erase(__old_end, end()); - throw; - } -#endif // _LIBCPP_NO_EXCEPTIONS - } - __p = std::rotate(__p, __old_end, end()); - insert(__p, __v.begin(), __v.end()); - return begin() + __off; -} - -template -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename enable_if -< - __is_cpp17_forward_iterator<_ForwardIterator>::value, - typename vector::iterator ->::type -vector::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) -{ - const difference_type __n_signed = std::distance(__first, __last); - _LIBCPP_ASSERT(__n_signed >= 0, "invalid range specified"); - const size_type __n = static_cast(__n_signed); - iterator __r; - size_type __c = capacity(); - if (__n <= __c && size() <= __c - __n) - { - const_iterator __old_end = end(); - __size_ += __n; - std::copy_backward(__position, __old_end, end()); - __r = __const_iterator_cast(__position); - } - else - { - vector __v(get_allocator()); - __v.reserve(__recommend(__size_ + __n)); - __v.__size_ = __size_ + __n; - __r = std::copy(cbegin(), __position, __v.begin()); - std::copy_backward(__position, cend(), __v.end()); - swap(__v); - } - std::copy(__first, __last, __r); - return __r; -} - -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename vector::iterator -vector::erase(const_iterator __position) -{ - iterator __r = __const_iterator_cast(__position); - std::copy(__position + 1, this->cend(), __r); - --__size_; - return __r; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -typename vector::iterator -vector::erase(const_iterator __first, const_iterator __last) -{ - iterator __r = __const_iterator_cast(__first); - difference_type __d = __last - __first; - std::copy(__last, this->cend(), __r); - __size_ -= __d; - return __r; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector::swap(vector& __x) -#if _LIBCPP_STD_VER >= 14 - _NOEXCEPT -#else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || - __is_nothrow_swappable::value) -#endif -{ - std::swap(this->__begin_, __x.__begin_); - std::swap(this->__size_, __x.__size_); - std::swap(this->__cap(), __x.__cap()); - std::__swap_allocator(this->__alloc(), __x.__alloc(), - integral_constant()); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector::resize(size_type __sz, value_type __x) -{ - size_type __cs = size(); - if (__cs < __sz) - { - iterator __r; - size_type __c = capacity(); - size_type __n = __sz - __cs; - if (__n <= __c && __cs <= __c - __n) - { - __r = end(); - __size_ += __n; - } - else - { - vector __v(get_allocator()); - __v.reserve(__recommend(__size_ + __n)); - __v.__size_ = __size_ + __n; - __r = std::copy(cbegin(), cend(), __v.begin()); - swap(__v); - } - std::fill_n(__r, __n, __x); - } - else - __size_ = __sz; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 void -vector::flip() _NOEXCEPT -{ - // do middle whole words - size_type __n = __size_; - __storage_pointer __p = __begin_; - for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word) - *__p = ~*__p; - // do last partial word - if (__n > 0) - { - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - __storage_type __b = *__p & __m; - *__p &= ~__m; - *__p |= ~__b & __m; - } -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 bool -vector::__invariants() const -{ - if (this->__begin_ == nullptr) - { - if (this->__size_ != 0 || this->__cap() != 0) - return false; - } - else - { - if (this->__cap() == 0) - return false; - if (this->__size_ > this->capacity()) - return false; - } - return true; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 size_t -vector::__hash_code() const _NOEXCEPT -{ - size_t __h = 0; - // do middle whole words - size_type __n = __size_; - __storage_pointer __p = __begin_; - for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word) - __h ^= *__p; - // do last partial word - if (__n > 0) - { - const __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - __h ^= *__p & __m; - } - return __h; -} - -template -struct _LIBCPP_TEMPLATE_VIS hash > - : public __unary_function, size_t> -{ - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - size_t operator()(const vector& __vec) const _NOEXCEPT - {return __vec.__hash_code();} -}; - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -bool -operator==(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) -{ - const typename vector<_Tp, _Allocator>::size_type __sz = __x.size(); - return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -bool -operator!=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) -{ - return !(__x == __y); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -bool -operator< (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) -{ - return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -bool -operator> (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) -{ - return __y < __x; -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -bool -operator>=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) -{ - return !(__x < __y); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -bool -operator<=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) -{ - return !(__y < __x); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI -void -swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); -} - -#if _LIBCPP_STD_VER > 17 -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::size_type -erase(vector<_Tp, _Allocator>& __c, const _Up& __v) { - auto __old_size = __c.size(); - __c.erase(std::remove(__c.begin(), __c.end(), __v), __c.end()); - return __old_size - __c.size(); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 -inline _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::size_type -erase_if(vector<_Tp, _Allocator>& __c, _Predicate __pred) { - auto __old_size = __c.size(); - __c.erase(std::remove_if(__c.begin(), __c.end(), __pred), __c.end()); - return __old_size - __c.size(); -} - -template <> -inline constexpr bool __format::__enable_insertable> = true; -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template <> -inline constexpr bool __format::__enable_insertable> = true; -#endif - -#endif // _LIBCPP_STD_VER > 17 - -#if _LIBCPP_STD_VER > 20 -template -// Since is-vector-bool-reference is only used once it's inlined here. - requires same_as> -struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Tp, CharT> { -private: - formatter __underlying_; - -public: - template - _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { - return __underlying_.parse(__ctx); - } - - template - _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _Tp& __ref, _FormatContext& __ctx) const { - return __underlying_.format(__ref, __ctx); - } -}; -#endif // _LIBCPP_STD_VER > 20 - -_LIBCPP_END_NAMESPACE_STD - -#if _LIBCPP_STD_VER > 14 -_LIBCPP_BEGIN_NAMESPACE_STD -namespace pmr { -template -using vector = std::vector<_ValueT, polymorphic_allocator<_ValueT>>; -} // namespace pmr -_LIBCPP_END_NAMESPACE_STD -#endif - -_LIBCPP_POP_MACROS - -#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 -# include -# include -# include -# include -# include -#endif - -#endif // _LIBCPP_VECTOR - -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_UNORDERED_MAP -#define _LIBCPP_UNORDERED_MAP - -/* - - unordered_map synopsis - -#include - -namespace std -{ - -template , class Pred = equal_to, - class Alloc = allocator>> -class unordered_map -{ -public: - // types - typedef Key key_type; - typedef T mapped_type; - typedef Hash hasher; - typedef Pred key_equal; - typedef Alloc allocator_type; - typedef pair value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef typename allocator_traits::size_type size_type; - typedef typename allocator_traits::difference_type difference_type; - - typedef /unspecified/ iterator; - typedef /unspecified/ const_iterator; - typedef /unspecified/ local_iterator; - typedef /unspecified/ const_local_iterator; - - typedef unspecified node_type; // C++17 - typedef INSERT_RETURN_TYPE insert_return_type; // C++17 - - unordered_map() - noexcept( - is_nothrow_default_constructible::value && - is_nothrow_default_constructible::value && - is_nothrow_default_constructible::value); - explicit unordered_map(size_type n, const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - 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()); - explicit unordered_map(const allocator_type&); - unordered_map(const unordered_map&); - unordered_map(const unordered_map&, const Allocator&); - unordered_map(unordered_map&&) - noexcept( - is_nothrow_move_constructible::value && - is_nothrow_move_constructible::value && - is_nothrow_move_constructible::value); - unordered_map(unordered_map&&, const Allocator&); - unordered_map(initializer_list, size_type n = 0, - const hasher& hf = hasher(), const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_map(size_type n, const allocator_type& a) - : unordered_map(n, hasher(), key_equal(), a) {} // C++14 - unordered_map(size_type n, const hasher& hf, const allocator_type& a) - : unordered_map(n, hf, key_equal(), a) {} // C++14 - template - unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a) - : unordered_map(f, l, n, hasher(), key_equal(), a) {} // C++14 - template - unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, - const allocator_type& a) - : unordered_map(f, l, n, hf, key_equal(), a) {} // C++14 - unordered_map(initializer_list il, size_type n, const allocator_type& a) - : unordered_map(il, n, hasher(), key_equal(), a) {} // C++14 - unordered_map(initializer_list il, size_type n, const hasher& hf, - const allocator_type& a) - : unordered_map(il, n, hf, key_equal(), a) {} // C++14 - ~unordered_map(); - unordered_map& operator=(const unordered_map&); - unordered_map& operator=(unordered_map&&) - noexcept( - allocator_type::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value); - unordered_map& operator=(initializer_list); - - allocator_type get_allocator() const noexcept; - - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - - iterator begin() noexcept; - iterator end() noexcept; - const_iterator begin() const noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - - template - pair emplace(Args&&... args); - template - iterator emplace_hint(const_iterator position, Args&&... args); - pair insert(const value_type& obj); - template - pair insert(P&& obj); - iterator insert(const_iterator hint, const value_type& obj); - template - iterator insert(const_iterator hint, P&& obj); - template - void insert(InputIterator first, InputIterator last); - void insert(initializer_list); - - node_type extract(const_iterator position); // C++17 - node_type extract(const key_type& x); // C++17 - insert_return_type insert(node_type&& nh); // C++17 - iterator insert(const_iterator hint, node_type&& nh); // C++17 - - template - pair try_emplace(const key_type& k, Args&&... args); // C++17 - template - pair try_emplace(key_type&& k, Args&&... args); // C++17 - template - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17 - template - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17 - template - pair insert_or_assign(const key_type& k, M&& obj); // C++17 - template - pair insert_or_assign(key_type&& k, M&& obj); // C++17 - template - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17 - template - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17 - - iterator erase(const_iterator position); - iterator erase(iterator position); // C++14 - size_type erase(const key_type& k); - iterator erase(const_iterator first, const_iterator last); - void clear() noexcept; - - template - void merge(unordered_map& source); // C++17 - template - void merge(unordered_map&& source); // C++17 - template - void merge(unordered_multimap& source); // C++17 - template - void merge(unordered_multimap&& source); // C++17 - - void swap(unordered_map&) - noexcept( - (!allocator_type::propagate_on_container_swap::value || - __is_nothrow_swappable::value) && - __is_nothrow_swappable::value && - __is_nothrow_swappable::value); - - hasher hash_function() const; - key_equal key_eq() const; - - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - template - iterator find(const K& x); // C++20 - template - const_iterator find(const K& x) const; // C++20 - size_type count(const key_type& k) const; - template - size_type count(const K& k) const; // C++20 - bool contains(const key_type& k) const; // C++20 - template - bool contains(const K& k) const; // C++20 - pair equal_range(const key_type& k); - pair equal_range(const key_type& k) const; - template - pair equal_range(const K& k); // C++20 - template - pair equal_range(const K& k) const; // C++20 - - mapped_type& operator[](const key_type& k); - mapped_type& operator[](key_type&& k); - - mapped_type& at(const key_type& k); - const mapped_type& at(const key_type& k) const; - - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - - local_iterator begin(size_type n); - local_iterator end(size_type n); - const_local_iterator begin(size_type n) const; - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; - - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); -}; - -template>, class Pred = equal_to>, - class Allocator = allocator>> -unordered_map(InputIterator, InputIterator, typename see below::size_type = see below, - Hash = Hash(), Pred = Pred(), Allocator = Allocator()) - -> unordered_map, iter_value_t, Hash, Pred, - Allocator>; // C++17 - -template, - class Pred = equal_to, class Allocator = allocator>> -unordered_map(initializer_list>, typename see below::size_type = see below, - Hash = Hash(), Pred = Pred(), Allocator = Allocator()) - -> unordered_map; // C++17 - -template -unordered_map(InputIterator, InputIterator, typename see below::size_type, Allocator) - -> unordered_map, iter_val_t, - hash>, equal_to>, Allocator>; // C++17 - -template -unordered_map(InputIterator, InputIterator, Allocator) - -> unordered_map, iter_val_t, - hash>, equal_to>, Allocator>; // C++17 - -template -unordered_map(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) - -> unordered_map, iter_val_t, Hash, - equal_to>, Allocator>; // C++17 - -template -unordered_map(initializer_list>, typename see below::size_type, Allocator) - -> unordered_map, equal_to, Allocator>; // C++17 - -template -unordered_map(initializer_list>, Allocator) - -> unordered_map, equal_to, Allocator>; // C++17 - -template -unordered_map(initializer_list>, typename see below::size_type, Hash, Allocator) - -> unordered_map, Allocator>; // C++17 - -template - void swap(unordered_map& x, - unordered_map& y) - noexcept(noexcept(x.swap(y))); - -template - bool - operator==(const unordered_map& x, - const unordered_map& y); - -template - bool - operator!=(const unordered_map& x, - const unordered_map& y); - -template , class Pred = equal_to, - class Alloc = allocator>> -class unordered_multimap -{ -public: - // types - typedef Key key_type; - typedef T mapped_type; - typedef Hash hasher; - typedef Pred key_equal; - typedef Alloc allocator_type; - typedef pair value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename allocator_traits::pointer pointer; - typedef typename allocator_traits::const_pointer const_pointer; - typedef typename allocator_traits::size_type size_type; - typedef typename allocator_traits::difference_type difference_type; - - typedef /unspecified/ iterator; - typedef /unspecified/ const_iterator; - typedef /unspecified/ local_iterator; - typedef /unspecified/ const_local_iterator; - - typedef unspecified node_type; // C++17 - - unordered_multimap() - noexcept( - is_nothrow_default_constructible::value && - is_nothrow_default_constructible::value && - is_nothrow_default_constructible::value); - explicit unordered_multimap(size_type n, const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - 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()); - explicit unordered_multimap(const allocator_type&); - unordered_multimap(const unordered_multimap&); - unordered_multimap(const unordered_multimap&, const Allocator&); - unordered_multimap(unordered_multimap&&) - noexcept( - is_nothrow_move_constructible::value && - is_nothrow_move_constructible::value && - is_nothrow_move_constructible::value); - unordered_multimap(unordered_multimap&&, const Allocator&); - unordered_multimap(initializer_list, size_type n = 0, - const hasher& hf = hasher(), const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_multimap(size_type n, const allocator_type& a) - : unordered_multimap(n, hasher(), key_equal(), a) {} // C++14 - unordered_multimap(size_type n, const hasher& hf, const allocator_type& a) - : unordered_multimap(n, hf, key_equal(), a) {} // C++14 - template - unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a) - : unordered_multimap(f, l, n, hasher(), key_equal(), a) {} // C++14 - template - unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, - const allocator_type& a) - : unordered_multimap(f, l, n, hf, key_equal(), a) {} // C++14 - unordered_multimap(initializer_list il, size_type n, const allocator_type& a) - : unordered_multimap(il, n, hasher(), key_equal(), a) {} // C++14 - unordered_multimap(initializer_list il, size_type n, const hasher& hf, - const allocator_type& a) - : unordered_multimap(il, n, hf, key_equal(), a) {} // C++14 - ~unordered_multimap(); - unordered_multimap& operator=(const unordered_multimap&); - unordered_multimap& operator=(unordered_multimap&&) - noexcept( - allocator_type::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value); - unordered_multimap& operator=(initializer_list); - - allocator_type get_allocator() const noexcept; - - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - - iterator begin() noexcept; - iterator end() noexcept; - const_iterator begin() const noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - - template - iterator emplace(Args&&... args); - template - iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& obj); - template - iterator insert(P&& obj); - iterator insert(const_iterator hint, const value_type& obj); - template - iterator insert(const_iterator hint, P&& obj); - template - void insert(InputIterator first, InputIterator last); - void insert(initializer_list); - - node_type extract(const_iterator position); // C++17 - node_type extract(const key_type& x); // C++17 - iterator insert(node_type&& nh); // C++17 - iterator insert(const_iterator hint, node_type&& nh); // C++17 - - iterator erase(const_iterator position); - iterator erase(iterator position); // C++14 - size_type erase(const key_type& k); - iterator erase(const_iterator first, const_iterator last); - void clear() noexcept; - - template - void merge(unordered_multimap& source); // C++17 - template - void merge(unordered_multimap&& source); // C++17 - template - void merge(unordered_map& source); // C++17 - template - void merge(unordered_map&& source); // C++17 - - void swap(unordered_multimap&) - noexcept( - (!allocator_type::propagate_on_container_swap::value || - __is_nothrow_swappable::value) && - __is_nothrow_swappable::value && - __is_nothrow_swappable::value); - - hasher hash_function() const; - key_equal key_eq() const; - - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; - template - iterator find(const K& x); // C++20 - template - const_iterator find(const K& x) const; // C++20 - size_type count(const key_type& k) const; - template - size_type count(const K& k) const; // C++20 - bool contains(const key_type& k) const; // C++20 - template - bool contains(const K& k) const; // C++20 - pair equal_range(const key_type& k); - pair equal_range(const key_type& k) const; - template - pair equal_range(const K& k); // C++20 - template - pair equal_range(const K& k) const; // C++20 - - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - - local_iterator begin(size_type n); - local_iterator end(size_type n); - const_local_iterator begin(size_type n) const; - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; - - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); -}; - -template>, class Pred = equal_to>, - class Allocator = allocator>> -unordered_multimap(InputIterator, InputIterator, typename see below::size_type = see below, - Hash = Hash(), Pred = Pred(), Allocator = Allocator()) - -> unordered_multimap, iter_value_t, Hash, Pred, - Allocator>; // C++17 - -template, - class Pred = equal_to, class Allocator = allocator>> -unordered_multimap(initializer_list>, typename see below::size_type = see below, - Hash = Hash(), Pred = Pred(), Allocator = Allocator()) - -> unordered_multimap; // C++17 - -template -unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Allocator) - -> unordered_multimap, iter_val_t, - hash>, equal_to>, Allocator>; // C++17 - -template -unordered_multimap(InputIterator, InputIterator, Allocator) - -> unordered_multimap, iter_val_t, - hash>, equal_to>, Allocator>; // C++17 - -template -unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) - -> unordered_multimap, iter_val_t, Hash, - equal_to>, Allocator>; // C++17 - -template -unordered_multimap(initializer_list>, typename see below::size_type, Allocator) - -> unordered_multimap, equal_to, Allocator>; // C++17 - -template -unordered_multimap(initializer_list>, Allocator) - -> unordered_multimap, equal_to, Allocator>; // C++17 - -template -unordered_multimap(initializer_list>, typename see below::size_type, Hash, - Allocator) - -> unordered_multimap, Allocator>; // C++17 - -template - void swap(unordered_multimap& x, - unordered_multimap& y) - noexcept(noexcept(x.swap(y))); - -template - typename unordered_map::size_type - erase_if(unordered_map& c, Predicate pred); // C++20 - -template - typename unordered_multimap::size_type - erase_if(unordered_multimap& c, Predicate pred); // C++20 - -template - bool - operator==(const unordered_multimap& x, - const unordered_multimap& y); - -template - bool - operator!=(const unordered_multimap& x, - const unordered_multimap& y); - -} // std - -*/ - -#include <__algorithm/is_permutation.h> -#include <__assert> // all public C++ headers provide the assertion handler -#include <__config> -#include <__debug> -#include <__functional/is_transparent.h> -#include <__functional/operations.h> -#include <__hash_table> -#include <__iterator/distance.h> -#include <__iterator/erase_if_container.h> -#include <__iterator/iterator_traits.h> -#include <__memory/addressof.h> -#include <__memory/allocator.h> -#include <__memory_resource/polymorphic_allocator.h> -#include <__node_handle> -#include <__type_traits/is_allocator.h> -#include <__utility/forward.h> -#include -#include -#include - -// standard-mandated includes - -// [iterator.range] -#include <__iterator/access.h> -#include <__iterator/data.h> -#include <__iterator/empty.h> -#include <__iterator/reverse_access.h> -#include <__iterator/size.h> - -// [unord.map.syn] -#include -#include - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - template ::value && !__libcpp_is_final<_Hash>::value> class __unordered_map_hasher @@ -7305,40 +2919,7 @@ class __unordered_map_equal<_Key, _Cp, _Pred, _Hash, false> public: _LIBCPP_INLINE_VISIBILITY __unordered_map_equal() - _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value) - : __pred_() {} - _LIBCPP_INLINE_VISIBILITY - __unordered_map_equal(const _Pred& __p) - _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value) - : __pred_(__p) {} - _LIBCPP_INLINE_VISIBILITY - const _Pred& key_eq() const _NOEXCEPT {return __pred_;} - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Cp& __x, const _Cp& __y) const - {return __pred_(__x.__get_value().first, __y.__get_value().first);} - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Cp& __x, const _Key& __y) const - {return __pred_(__x.__get_value().first, __y);} - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Key& __x, const _Cp& __y) const - {return __pred_(__x, __y.__get_value().first);} -#if _LIBCPP_STD_VER > 17 - template - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Cp& __x, const _K2& __y) const - {return __pred_(__x.__get_value().first, __y);} - template - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _K2& __x, const _Cp& __y) const - {return __pred_(__x, __y.__get_value().first);} - template - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Key& __x, const _K2& __y) const - {return __pred_(__x, __y);} - template - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _K2& __x, const _Key& __y) const - {return __pred_(__x, __y);} + _NOEXCEPT_(is_nothrow_default_constructibl_x, __y);} #endif _LIBCPP_INLINE_VISIBILITY void swap(__unordered_map_equal& __y) @@ -7468,768 +3049,6 @@ public: _VSTD::move(__v.second)); } - _LIBCPP_INLINE_VISIBILITY - __hash_value_type& operator=(const __hash_value_type& __v) - { - __ref() = __v.__get_value(); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __hash_value_type& operator=(__hash_value_type&& __v) - { - __ref() = __v.__move(); - return *this; - } - - template ::value> - > - _LIBCPP_INLINE_VISIBILITY - __hash_value_type& operator=(_ValueTp&& __v) - { - __ref() = _VSTD::forward<_ValueTp>(__v); - return *this; - } - -private: - __hash_value_type(const __hash_value_type& __v) = delete; - __hash_value_type(__hash_value_type&& __v) = delete; - template - explicit __hash_value_type(_Args&& ...__args) = delete; - - ~__hash_value_type() = delete; -}; - -#else - -template -struct __hash_value_type -{ - typedef _Key key_type; - typedef _Tp mapped_type; - typedef pair value_type; - -private: - value_type __cc_; - -public: - _LIBCPP_INLINE_VISIBILITY - value_type& __get_value() { return __cc_; } - _LIBCPP_INLINE_VISIBILITY - const value_type& __get_value() const { return __cc_; } - -private: - ~__hash_value_type(); -}; - -#endif - -template -class _LIBCPP_TEMPLATE_VIS __hash_map_iterator -{ - _HashIterator __i_; - - typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes; - -public: - typedef forward_iterator_tag iterator_category; - typedef typename _NodeTypes::__map_value_type value_type; - typedef typename _NodeTypes::difference_type difference_type; - typedef value_type& reference; - typedef typename _NodeTypes::__map_value_type_pointer pointer; - - _LIBCPP_INLINE_VISIBILITY - __hash_map_iterator() _NOEXCEPT {} - - _LIBCPP_INLINE_VISIBILITY - __hash_map_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {} - - _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __i_->__get_value();} - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const {return pointer_traits::pointer_to(__i_->__get_value());} - - _LIBCPP_INLINE_VISIBILITY - __hash_map_iterator& operator++() {++__i_; return *this;} - _LIBCPP_INLINE_VISIBILITY - __hash_map_iterator operator++(int) - { - __hash_map_iterator __t(*this); - ++(*this); - return __t; - } - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y) - {return __x.__i_ == __y.__i_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y) - {return __x.__i_ != __y.__i_;} - - template friend class _LIBCPP_TEMPLATE_VIS unordered_map; - template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; - template friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; - template friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; - template friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; -}; - -template -class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator -{ - _HashIterator __i_; - - typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes; - -public: - typedef forward_iterator_tag iterator_category; - typedef typename _NodeTypes::__map_value_type value_type; - typedef typename _NodeTypes::difference_type difference_type; - typedef const value_type& reference; - typedef typename _NodeTypes::__const_map_value_type_pointer pointer; - - _LIBCPP_INLINE_VISIBILITY - __hash_map_const_iterator() _NOEXCEPT {} - - _LIBCPP_INLINE_VISIBILITY - __hash_map_const_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {} - _LIBCPP_INLINE_VISIBILITY - __hash_map_const_iterator( - __hash_map_iterator __i) - _NOEXCEPT - : __i_(__i.__i_) {} - - _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __i_->__get_value();} - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const {return pointer_traits::pointer_to(__i_->__get_value());} - - _LIBCPP_INLINE_VISIBILITY - __hash_map_const_iterator& operator++() {++__i_; return *this;} - _LIBCPP_INLINE_VISIBILITY - __hash_map_const_iterator operator++(int) - { - __hash_map_const_iterator __t(*this); - ++(*this); - return __t; - } - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) - {return __x.__i_ == __y.__i_;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) - {return __x.__i_ != __y.__i_;} - - template friend class _LIBCPP_TEMPLATE_VIS unordered_map; - template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; - template friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; - template friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; -}; - -template -class unordered_multimap; - -template , class _Pred = equal_to<_Key>, - class _Alloc = allocator > > -class _LIBCPP_TEMPLATE_VIS unordered_map -{ -public: - // types - typedef _Key key_type; - typedef _Tp mapped_type; - typedef __type_identity_t<_Hash> hasher; - typedef __type_identity_t<_Pred> key_equal; - typedef __type_identity_t<_Alloc> allocator_type; - typedef pair value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - static_assert((is_same::value), - "Invalid allocator::value_type"); - -private: - typedef __hash_value_type __value_type; - typedef __unordered_map_hasher __hasher; - typedef __unordered_map_equal __key_equal; - typedef __rebind_alloc, __value_type> __allocator_type; - - typedef __hash_table<__value_type, __hasher, - __key_equal, __allocator_type> __table; - - __table __table_; - - typedef typename __table::_NodeTypes _NodeTypes; - typedef typename __table::__node_pointer __node_pointer; - typedef typename __table::__node_const_pointer __node_const_pointer; - typedef typename __table::__node_traits __node_traits; - typedef typename __table::__node_allocator __node_allocator; - typedef typename __table::__node __node; - typedef __hash_map_node_destructor<__node_allocator> _Dp; - typedef unique_ptr<__node, _Dp> __node_holder; - typedef allocator_traits __alloc_traits; - - static_assert(is_same >::value, - "[allocator.requirements] states that rebinding an allocator to the same type should result in the " - "original allocator"); - - static_assert((is_same::value), ""); - static_assert((is_same::value), ""); -public: - typedef typename __alloc_traits::pointer pointer; - typedef typename __alloc_traits::const_pointer const_pointer; - typedef typename __table::size_type size_type; - typedef typename __table::difference_type difference_type; - - typedef __hash_map_iterator iterator; - typedef __hash_map_const_iterator const_iterator; - typedef __hash_map_iterator local_iterator; - typedef __hash_map_const_iterator const_local_iterator; - -#if _LIBCPP_STD_VER > 14 - typedef __map_node_handle<__node, allocator_type> node_type; - typedef __insert_return_type insert_return_type; -#endif - - template - friend class _LIBCPP_TEMPLATE_VIS unordered_map; - template - friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; - - _LIBCPP_INLINE_VISIBILITY - unordered_map() - _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - { - _VSTD::__debug_db_insert_c(this); - } - explicit unordered_map(size_type __n, const hasher& __hf = hasher(), - const key_equal& __eql = key_equal()); - unordered_map(size_type __n, const hasher& __hf, - const key_equal& __eql, - const allocator_type& __a); - template - unordered_map(_InputIterator __first, _InputIterator __last); - template - unordered_map(_InputIterator __first, _InputIterator __last, - size_type __n, const hasher& __hf = hasher(), - const key_equal& __eql = key_equal()); - template - unordered_map(_InputIterator __first, _InputIterator __last, - size_type __n, const hasher& __hf, - const key_equal& __eql, - const allocator_type& __a); - _LIBCPP_INLINE_VISIBILITY - explicit unordered_map(const allocator_type& __a); - unordered_map(const unordered_map& __u); - unordered_map(const unordered_map& __u, const allocator_type& __a); -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - unordered_map(unordered_map&& __u) - _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); - unordered_map(unordered_map&& __u, const allocator_type& __a); - unordered_map(initializer_list __il); - unordered_map(initializer_list __il, size_type __n, - const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); - unordered_map(initializer_list __il, size_type __n, - const hasher& __hf, const key_equal& __eql, - const allocator_type& __a); -#endif // _LIBCPP_CXX03_LANG -#if _LIBCPP_STD_VER > 11 - _LIBCPP_INLINE_VISIBILITY - unordered_map(size_type __n, const allocator_type& __a) - : unordered_map(__n, hasher(), key_equal(), __a) {} - _LIBCPP_INLINE_VISIBILITY - unordered_map(size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_map(__n, __hf, key_equal(), __a) {} - template - _LIBCPP_INLINE_VISIBILITY - unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) - : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) {} - template - _LIBCPP_INLINE_VISIBILITY - 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) {} - _LIBCPP_INLINE_VISIBILITY - unordered_map(initializer_list __il, size_type __n, const allocator_type& __a) - : unordered_map(__il, __n, hasher(), key_equal(), __a) {} - _LIBCPP_INLINE_VISIBILITY - unordered_map(initializer_list __il, size_type __n, const hasher& __hf, - const allocator_type& __a) - : unordered_map(__il, __n, __hf, key_equal(), __a) {} -#endif - _LIBCPP_INLINE_VISIBILITY - ~unordered_map() { - static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), ""); - } - - _LIBCPP_INLINE_VISIBILITY - unordered_map& operator=(const unordered_map& __u) - { -#ifndef _LIBCPP_CXX03_LANG - __table_ = __u.__table_; -#else - if (this != _VSTD::addressof(__u)) { - __table_.clear(); - __table_.hash_function() = __u.__table_.hash_function(); - __table_.key_eq() = __u.__table_.key_eq(); - __table_.max_load_factor() = __u.__table_.max_load_factor(); - __table_.__copy_assign_alloc(__u.__table_); - insert(__u.begin(), __u.end()); - } -#endif - return *this; - } -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - unordered_map& operator=(unordered_map&& __u) - _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); - _LIBCPP_INLINE_VISIBILITY - unordered_map& operator=(initializer_list __il); -#endif // _LIBCPP_CXX03_LANG - - _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT - {return allocator_type(__table_.__node_alloc());} - - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - bool empty() const _NOEXCEPT {return __table_.size() == 0;} - _LIBCPP_INLINE_VISIBILITY - size_type size() const _NOEXCEPT {return __table_.size();} - _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT {return __table_.max_size();} - - _LIBCPP_INLINE_VISIBILITY - iterator begin() _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - iterator end() _NOEXCEPT {return __table_.end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator end() const _NOEXCEPT {return __table_.end();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cbegin() const _NOEXCEPT {return __table_.begin();} - _LIBCPP_INLINE_VISIBILITY - const_iterator cend() const _NOEXCEPT {return __table_.end();} - - _LIBCPP_INLINE_VISIBILITY - pair insert(const value_type& __x) - {return __table_.__insert_unique(__x);} - - iterator insert(const_iterator __p, const value_type& __x) { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered_map::insert(const_iterator, const value_type&) called with an iterator not " - "referring to this unordered_map"); - ((void)__p); - return insert(__x).first; - } - - template - _LIBCPP_INLINE_VISIBILITY - void insert(_InputIterator __first, _InputIterator __last); - -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - void insert(initializer_list __il) - {insert(__il.begin(), __il.end());} - - _LIBCPP_INLINE_VISIBILITY - pair insert(value_type&& __x) - {return __table_.__insert_unique(_VSTD::move(__x));} - - iterator insert(const_iterator __p, value_type&& __x) { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" - " referring to this unordered_map"); - ((void)__p); - return __table_.__insert_unique(_VSTD::move(__x)).first; - } - - template ::value> > - _LIBCPP_INLINE_VISIBILITY - pair insert(_Pp&& __x) - {return __table_.__insert_unique(_VSTD::forward<_Pp>(__x));} - - template ::value> > - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, _Pp&& __x) - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered_map::insert(const_iterator, value_type&&) called with an iterator not" - " referring to this unordered_map"); - ((void)__p); - return insert(_VSTD::forward<_Pp>(__x)).first; - } - - template - _LIBCPP_INLINE_VISIBILITY - pair emplace(_Args&&... __args) { - return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...); - } - - template - _LIBCPP_INLINE_VISIBILITY - iterator emplace_hint(const_iterator __p, _Args&&... __args) { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered_map"); - ((void)__p); - return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; - } - -#endif // _LIBCPP_CXX03_LANG - -#if _LIBCPP_STD_VER > 14 - template - _LIBCPP_INLINE_VISIBILITY - pair try_emplace(const key_type& __k, _Args&&... __args) - { - return __table_.__emplace_unique_key_args(__k, piecewise_construct, - _VSTD::forward_as_tuple(__k), - _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); - } - - template - _LIBCPP_INLINE_VISIBILITY - pair try_emplace(key_type&& __k, _Args&&... __args) - { - return __table_.__emplace_unique_key_args(__k, piecewise_construct, - _VSTD::forward_as_tuple(_VSTD::move(__k)), - _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); - } - - template - _LIBCPP_INLINE_VISIBILITY - iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this, - "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" - " referring to this unordered_map"); - ((void)__h); - return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first; - } - - template - _LIBCPP_INLINE_VISIBILITY - iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) - { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this, - "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" - " referring to this unordered_map"); - ((void)__h); - return try_emplace(_VSTD::move(__k), _VSTD::forward<_Args>(__args)...).first; - } - - template - _LIBCPP_INLINE_VISIBILITY - pair insert_or_assign(const key_type& __k, _Vp&& __v) - { - pair __res = __table_.__emplace_unique_key_args(__k, - __k, _VSTD::forward<_Vp>(__v)); - if (!__res.second) { - __res.first->second = _VSTD::forward<_Vp>(__v); - } - return __res; - } - - template - _LIBCPP_INLINE_VISIBILITY - pair insert_or_assign(key_type&& __k, _Vp&& __v) - { - pair __res = __table_.__emplace_unique_key_args(__k, - _VSTD::move(__k), _VSTD::forward<_Vp>(__v)); - if (!__res.second) { - __res.first->second = _VSTD::forward<_Vp>(__v); - } - return __res; - } - - template - _LIBCPP_INLINE_VISIBILITY - iterator insert_or_assign(const_iterator, const key_type& __k, _Vp&& __v) - { - // FIXME: Add debug mode checking for the iterator input - return insert_or_assign(__k, _VSTD::forward<_Vp>(__v)).first; - } - - template - _LIBCPP_INLINE_VISIBILITY - iterator insert_or_assign(const_iterator, key_type&& __k, _Vp&& __v) - { - // FIXME: Add debug mode checking for the iterator input - return insert_or_assign(_VSTD::move(__k), _VSTD::forward<_Vp>(__v)).first; - } -#endif // _LIBCPP_STD_VER > 14 - - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);} - _LIBCPP_INLINE_VISIBILITY - iterator erase(iterator __p) {return __table_.erase(__p.__i_);} - _LIBCPP_INLINE_VISIBILITY - size_type erase(const key_type& __k) {return __table_.__erase_unique(__k);} - _LIBCPP_INLINE_VISIBILITY - iterator erase(const_iterator __first, const_iterator __last) - {return __table_.erase(__first.__i_, __last.__i_);} - _LIBCPP_INLINE_VISIBILITY - void clear() _NOEXCEPT {__table_.clear();} - -#if _LIBCPP_STD_VER > 14 - _LIBCPP_INLINE_VISIBILITY - insert_return_type insert(node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to unordered_map::insert()"); - return __table_.template __node_handle_insert_unique< - node_type, insert_return_type>(_VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __hint, node_type&& __nh) - { - _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to unordered_map::insert()"); - return __table_.template __node_handle_insert_unique( - __hint.__i_, _VSTD::move(__nh)); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(key_type const& __key) - { - return __table_.template __node_handle_extract(__key); - } - _LIBCPP_INLINE_VISIBILITY - node_type extract(const_iterator __it) - { - return __table_.template __node_handle_extract( - __it.__i_); - } - - template - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_map& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_unique(__source.__table_); - } - template - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_map&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_unique(__source.__table_); - } - template - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_multimap& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_unique(__source.__table_); - } - template - _LIBCPP_INLINE_VISIBILITY - void merge(unordered_multimap&& __source) - { - _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); - return __table_.__node_handle_merge_unique(__source.__table_); - } -#endif - - _LIBCPP_INLINE_VISIBILITY - void swap(unordered_map& __u) - _NOEXCEPT_(__is_nothrow_swappable<__table>::value) - { __table_.swap(__u.__table_);} - - _LIBCPP_INLINE_VISIBILITY - hasher hash_function() const - {return __table_.hash_function().hash_function();} - _LIBCPP_INLINE_VISIBILITY - key_equal key_eq() const - {return __table_.key_eq().key_eq();} - - _LIBCPP_INLINE_VISIBILITY - iterator find(const key_type& __k) {return __table_.find(__k);} - _LIBCPP_INLINE_VISIBILITY - const_iterator find(const key_type& __k) const {return __table_.find(__k);} -#if _LIBCPP_STD_VER > 17 - template ::value && __is_transparent::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - iterator find(const _K2& __k) {return __table_.find(__k);} - template ::value && __is_transparent::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - const_iterator find(const _K2& __k) const {return __table_.find(__k);} -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - size_type count(const key_type& __k) const {return __table_.__count_unique(__k);} -#if _LIBCPP_STD_VER > 17 - template ::value && __is_transparent::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - size_type count(const _K2& __k) const {return __table_.__count_unique(__k);} -#endif // _LIBCPP_STD_VER > 17 - -#if _LIBCPP_STD_VER > 17 - _LIBCPP_INLINE_VISIBILITY - bool contains(const key_type& __k) const {return find(__k) != end();} - - template ::value && __is_transparent::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - bool contains(const _K2& __k) const {return find(__k) != end();} -#endif // _LIBCPP_STD_VER > 17 - - _LIBCPP_INLINE_VISIBILITY - pair equal_range(const key_type& __k) - {return __table_.__equal_range_unique(__k);} - _LIBCPP_INLINE_VISIBILITY - pair equal_range(const key_type& __k) const - {return __table_.__equal_range_unique(__k);} -#if _LIBCPP_STD_VER > 17 - template ::value && __is_transparent::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - pair equal_range(const _K2& __k) - {return __table_.__equal_range_unique(__k);} - template ::value && __is_transparent::value>* = nullptr> - _LIBCPP_INLINE_VISIBILITY - pair equal_range(const _K2& __k) const - {return __table_.__equal_range_unique(__k);} -#endif // _LIBCPP_STD_VER > 17 - - mapped_type& operator[](const key_type& __k); -#ifndef _LIBCPP_CXX03_LANG - mapped_type& operator[](key_type&& __k); -#endif - - mapped_type& at(const key_type& __k); - const mapped_type& at(const key_type& __k) const; - - _LIBCPP_INLINE_VISIBILITY - size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} - _LIBCPP_INLINE_VISIBILITY - size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();} - - _LIBCPP_INLINE_VISIBILITY - size_type bucket_size(size_type __n) const - {return __table_.bucket_size(__n);} - _LIBCPP_INLINE_VISIBILITY - size_type bucket(const key_type& __k) const {return __table_.bucket(__k);} - - _LIBCPP_INLINE_VISIBILITY - local_iterator begin(size_type __n) {return __table_.begin(__n);} - _LIBCPP_INLINE_VISIBILITY - local_iterator end(size_type __n) {return __table_.end(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator begin(size_type __n) const {return __table_.cbegin(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator end(size_type __n) const {return __table_.cend(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator cbegin(size_type __n) const {return __table_.cbegin(__n);} - _LIBCPP_INLINE_VISIBILITY - const_local_iterator cend(size_type __n) const {return __table_.cend(__n);} - - _LIBCPP_INLINE_VISIBILITY - float load_factor() const _NOEXCEPT {return __table_.load_factor();} - _LIBCPP_INLINE_VISIBILITY - float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();} - _LIBCPP_INLINE_VISIBILITY - void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);} - _LIBCPP_INLINE_VISIBILITY - void rehash(size_type __n) {__table_.__rehash_unique(__n);} - _LIBCPP_INLINE_VISIBILITY - void reserve(size_type __n) {__table_.__reserve_unique(__n);} - -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - - bool __dereferenceable(const const_iterator* __i) const - {return __table_.__dereferenceable(_VSTD::addressof(__i->__i_));} - bool __decrementable(const const_iterator* __i) const - {return __table_.__decrementable(_VSTD::addressof(__i->__i_));} - bool __addable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);} - bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);} - -#endif // _LIBCPP_ENABLE_DEBUG_MODE - -private: - -#ifdef _LIBCPP_CXX03_LANG - __node_holder __construct_node_with_key(const key_type& __k); -#endif -}; - -#if _LIBCPP_STD_VER >= 17 -template>, - class _Pred = equal_to<__iter_key_type<_InputIterator>>, - class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>, - class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, - class = enable_if_t::value>, - class = enable_if_t::value>, - class = enable_if_t::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type = 0, - _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) - -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Hash, _Pred, _Allocator>; - -template>, - class _Pred = equal_to>, - class _Allocator = allocator>, - class = enable_if_t::value>, - class = enable_if_t::value>, - class = enable_if_t::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(initializer_list>, typename allocator_traits<_Allocator>::size_type = 0, - _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) - -> unordered_map, _Tp, _Hash, _Pred, _Allocator>; - -template::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator) - -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, - hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; - -template::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(_InputIterator, _InputIterator, _Allocator) - -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, - hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; - -template::value>, - class = enable_if_t::value>, - class = enable_if_t::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) - -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, - _Hash, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; - -template::value>> -unordered_map(initializer_list>, typename allocator_traits<_Allocator>::size_type, _Allocator) - -> unordered_map, _Tp, - hash>, - equal_to>, _Allocator>; - -template::value>> -unordered_map(initializer_list>, _Allocator) - -> unordered_map, _Tp, - hash>, - equal_to>, _Allocator>; - -template::value>, - class = enable_if_t::value>, - class = enable_if_t<__is_allocator<_Allocator>::value>> -unordered_map(initializer_list>, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) - -> unordered_map, _Tp, _Hash, - equal_to>, _Allocator>; -#endif - template unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( size_type __n, const hasher& __hf, const key_equal& __eql) @@ -8460,7 +3279,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k) { iterator __i = find(__k); if (__i == end()) - __throw_out_of_range("unordered_map::at: key not found"); + __throw_out_of_range(); return __i->second; } @@ -8470,7 +3289,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::at(const key_type& __k) const { const_iterator __i = find(__k); if (__i == end()) - __throw_out_of_range("unordered_map::at: key not found"); + __throw_out_of_range(); return __i->second; } @@ -8538,7 +3357,7 @@ public: typedef value_type& reference; typedef const value_type& const_reference; static_assert((is_same::value), - "Invalid allocator::value_type"); + ); private: typedef __hash_value_type __value_type; @@ -8560,11 +3379,11 @@ private: typedef allocator_traits __alloc_traits; static_assert((is_same::value), - "Allocator uses different size_type for different types"); + ); static_assert(is_same >::value, - "[allocator.requirements] states that rebinding an allocator to the same type should result in the " - "original allocator"); + + ); public: typedef typename __alloc_traits::pointer pointer; @@ -8651,7 +3470,7 @@ private: #endif _LIBCPP_INLINE_VISIBILITY ~unordered_multimap() { - static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), ""); + static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), ); } _LIBCPP_INLINE_VISIBILITY @@ -8766,7 +3585,7 @@ private: iterator insert(node_type&& __nh) { _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to unordered_multimap::insert()"); + ); return __table_.template __node_handle_insert_multi( _VSTD::move(__nh)); } @@ -8774,7 +3593,7 @@ private: iterator insert(const_iterator __hint, node_type&& __nh) { _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), - "node_type with incompatible allocator passed to unordered_multimap::insert()"); + ); return __table_.template __node_handle_insert_multi( __hint.__i_, _VSTD::move(__nh)); } @@ -8795,7 +3614,7 @@ private: void merge(unordered_multimap& __source) { _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + ); return __table_.__node_handle_merge_multi(__source.__table_); } template @@ -8803,7 +3622,7 @@ private: void merge(unordered_multimap&& __source) { _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + ); return __table_.__node_handle_merge_multi(__source.__table_); } template @@ -8811,7 +3630,7 @@ private: void merge(unordered_map& __source) { _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + ); return __table_.__node_handle_merge_multi(__source.__table_); } template @@ -8819,7 +3638,7 @@ private: void merge(unordered_map&& __source) { _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), - "merging container with incompatible allocator"); + ); return __table_.__node_handle_merge_multi(__source.__table_); } #endif @@ -9005,259 +3824,3 @@ unordered_multimap(initializer_list>, typename allocator_traits< -> unordered_multimap, _Tp, _Hash, equal_to>, _Allocator>; #endif - -template -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - size_type __n, const hasher& __hf, const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.__rehash_multi(__n); -} - -template -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a) - : __table_(__hf, __eql, typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - __table_.__rehash_multi(__n); -} - -template -template -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - _InputIterator __first, _InputIterator __last) -{ - _VSTD::__debug_db_insert_c(this); - insert(__first, __last); -} - -template -template -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - _InputIterator __first, _InputIterator __last, size_type __n, - const hasher& __hf, const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.__rehash_multi(__n); - insert(__first, __last); -} - -template -template -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - _InputIterator __first, _InputIterator __last, size_type __n, - const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - __table_.__rehash_multi(__n); - insert(__first, __last); -} - -template -inline -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - const allocator_type& __a) - : __table_(typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); -} - -template -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - const unordered_multimap& __u) - : __table_(__u.__table_) -{ - _VSTD::__debug_db_insert_c(this); - __table_.__rehash_multi(__u.bucket_count()); - insert(__u.begin(), __u.end()); -} - -template -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - const unordered_multimap& __u, const allocator_type& __a) - : __table_(__u.__table_, typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - __table_.__rehash_multi(__u.bucket_count()); - insert(__u.begin(), __u.end()); -} - -#ifndef _LIBCPP_CXX03_LANG - -template -inline -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - unordered_multimap&& __u) - _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) - : __table_(_VSTD::move(__u.__table_)) -{ - _VSTD::__debug_db_insert_c(this); - std::__debug_db_swap(this, std::addressof(__u)); -} - -template -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - unordered_multimap&& __u, const allocator_type& __a) - : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - if (__a != __u.get_allocator()) - { - iterator __i = __u.begin(); - while (__u.size() != 0) - { - __table_.__insert_multi( - __u.__table_.remove((__i++).__i_)->__value_.__move()); - } - } - else - std::__debug_db_swap(this, std::addressof(__u)); -} - -template -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - initializer_list __il) -{ - _VSTD::__debug_db_insert_c(this); - insert(__il.begin(), __il.end()); -} - -template -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - initializer_list __il, size_type __n, const hasher& __hf, - const key_equal& __eql) - : __table_(__hf, __eql) -{ - _VSTD::__debug_db_insert_c(this); - __table_.__rehash_multi(__n); - insert(__il.begin(), __il.end()); -} - -template -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( - initializer_list __il, size_type __n, const hasher& __hf, - const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, typename __table::allocator_type(__a)) -{ - _VSTD::__debug_db_insert_c(this); - __table_.__rehash_multi(__n); - insert(__il.begin(), __il.end()); -} - -template -inline -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_multimap&& __u) - _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) -{ - __table_ = _VSTD::move(__u.__table_); - return *this; -} - -template -inline -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=( - initializer_list __il) -{ - __table_.__assign_multi(__il.begin(), __il.end()); - return *this; -} - -#endif // _LIBCPP_CXX03_LANG - - - -template -template -inline -void -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, - _InputIterator __last) -{ - for (; __first != __last; ++__first) - __table_.__insert_multi(*__first); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -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); -} - -#if _LIBCPP_STD_VER > 17 -template -inline _LIBCPP_INLINE_VISIBILITY - typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type - erase_if(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, - _Predicate __pred) { - return _VSTD::__libcpp_erase_if_container(__c, __pred); -} -#endif - -template -_LIBCPP_HIDE_FROM_ABI bool -operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, - const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) -{ - if (__x.size() != __y.size()) - return false; - typedef typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::const_iterator - const_iterator; - typedef pair _EqRng; - for (const_iterator __i = __x.begin(), __ex = __x.end(); __i != __ex;) - { - _EqRng __xeq = __x.equal_range(__i->first); - _EqRng __yeq = __y.equal_range(__i->first); - if (_VSTD::distance(__xeq.first, __xeq.second) != - _VSTD::distance(__yeq.first, __yeq.second) || - !_VSTD::is_permutation(__xeq.first, __xeq.second, __yeq.first)) - return false; - __i = __xeq.second; - } - return true; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, - const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) -{ - return !(__x == __y); -} - -_LIBCPP_END_NAMESPACE_STD - -#if _LIBCPP_STD_VER > 14 -_LIBCPP_BEGIN_NAMESPACE_STD -namespace pmr { -template , class _PredT = std::equal_to<_KeyT>> -using unordered_map = - std::unordered_map<_KeyT, _ValueT, _HashT, _PredT, polymorphic_allocator>>; - -template , class _PredT = std::equal_to<_KeyT>> -using unordered_multimap = - std::unordered_multimap<_KeyT, _ValueT, _HashT, _PredT, polymorphic_allocator>>; -} // namespace pmr -_LIBCPP_END_NAMESPACE_STD -#endif - -#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 -# include -# include -# include -# include -#endif - -#endif // _LIBCPP_UNORDERED_MAP \ No newline at end of file diff --git a/ref_java b/ref_java index b8362cd..02ff751 100644 --- a/ref_java +++ b/ref_java @@ -7,42 +7,42 @@ import java.util.Objects; public class CaskBootstrap { public static void main(String[] args) { - InputStream manifest = CaskBootstrap.class.getClassLoader().getResourceAsStream("MANIFEST"); + InputStream manifest = CaskBootstrap.class.getClassLoader().getResourceAsStream(); if(manifest == null) { - throw new RuntimeException("The MANIFEST file for Cask is missing."); + throw new RuntimeException(); } String data; try { data = new String(manifest.readAllBytes()); manifest.close(); } catch (IOException e) { - throw new RuntimeException("The MANIFEST file for Cask is not readable."); + throw new RuntimeException(); } // Primarily just future-proofing. HashMap manifestMap = new HashMap<>(); - String[] properties = data.replace("\r", "").split("\n"); + String[] properties = data.replace(); for (String property : properties) { - int index = property.indexOf(":"); + int index = property.indexOf(); if (index == -1) { - throw new RuntimeException("Invalid property in MANIFEST: " + property); + throw new RuntimeException( + property); } manifestMap.put(property.substring(0, index).trim(), property.substring(index + 1).trim()); } - String mainClass = manifestMap.get("Main-Class"); - String caskFile = manifestMap.get("Cask-File"); + String mainClass = manifestMap.get(); + String caskFile = manifestMap.get(); if (mainClass == null || caskFile == null) { - throw new RuntimeException("The MANIFEST file for Cask is missing required properties."); + throw new RuntimeException(); } try { CaskClassLoader caskClassLoader = new CaskClassLoader(Objects.requireNonNull(CaskBootstrap.class.getClassLoader().getResourceAsStream(caskFile))); Class mainClassObject = caskClassLoader.loadClass(mainClass); Thread.currentThread().setContextClassLoader(caskClassLoader); - System.setProperty("java.system.class.loader", CaskClassLoader.class.getName()); - mainClassObject.getMethod("main", String[].class).invoke(null, (Object) args); + System.setProperty(, CaskClassLoader.class.getName()); + mainClassObject.getMethod(, String[].class).invoke(null, (Object) args); } catch (Exception e) { - throw new RuntimeException("Could not start Cask application.", e); + throw new RuntimeException(, e); } } } @@ -77,7 +77,7 @@ public class Encode extends PrimitiveFunction implements Lambda { @Override protected String name() { - return "encode"; + return ; } } @@ -110,7 +110,7 @@ public class Wget extends PrimitiveFunction implements Lambda { @Override protected String name() { - return "net:wget"; + return ; } } @@ -230,7 +230,7 @@ public class ArcNetProvider implements NetProvider{ Connect c = new Connect(); c.addressTCP = ip; - Log.debug("&bReceived connection: @", c.addressTCP); + Log.debug(, c.addressTCP); connection.setArbitraryData(kn); connections.add(kn); @@ -255,7 +255,7 @@ public class ArcNetProvider implements NetProvider{ if(!(connection.getArbitraryData() instanceof ArcConnection k) || !(object instanceof Packet pack)) return; if(packetSpamLimit > 0 && !k.packetRate.allow(3000, packetSpamLimit)){ - Log.warn("Blacklisting IP '@' as potential DOS attack - packet spam.", k.address); + Log.warn(, k.address); connection.close(DcReason.closed); netServer.admins.blacklistDos(k.address); return; @@ -294,7 +294,7 @@ public class ArcNetProvider implements NetProvider{ //just in case client.stop(); - Threads.daemon("Net Client", () -> { + Threads.daemon(, () -> { try{ client.run(); }catch(Exception e){ @@ -338,7 +338,7 @@ public class ArcNetProvider implements NetProvider{ Core.app.post(() -> valid.get(host)); }catch(IOException e){ if(port == Vars.port){ - for(var record : ArcDns.getSrvRecords("_mindustry._tcp." + address)){ + for(var record : ArcDns.getSrvRecords( + address)){ try{ var host = pingHostImpl(record.target, record.port); Core.app.post(() -> valid.get(host)); @@ -417,7 +417,7 @@ public class ArcNetProvider implements NetProvider{ }catch(Throwable e){ if(!(e instanceof ClosedSelectorException)) Threads.throwAppException(e); } - }, "Net Server"); + }, ); serverThread.setDaemon(true); serverThread.start(); } @@ -476,7 +476,7 @@ public class ArcNetProvider implements NetProvider{ } }catch(Exception e){ Log.err(e); - Log.info("Error sending packet. Disconnecting invalid client!"); + Log.info(); connection.close(DcReason.error); if(connection.getArbitraryData() instanceof ArcConnection k){ @@ -511,7 +511,7 @@ public class ArcNetProvider implements NetProvider{ lastDownload = Time.millis(); download.add(downloadAccum); downloadAccum = 0; - Log.info("Download: @ b/s", download.mean()); + Log.info(, download.mean()); } downloadAccum += byteBuffer.remaining(); } @@ -562,7 +562,7 @@ public class ArcNetProvider implements NetProvider{ byteBuffer.put((byte)-2); //code for framework message writeFramework(byteBuffer, msg); }else{ - if(!(o instanceof Packet pack)) throw new RuntimeException("All sent objects must implement be Packets! Class: " + o.getClass()); + if(!(o instanceof Packet pack)) throw new RuntimeException( + o.getClass()); byte id = Net.getPacketId(pack); byteBuffer.put(id); @@ -595,7 +595,7 @@ public class ArcNetProvider implements NetProvider{ lastUpload = Time.millis(); upload.add(uploadAccum); uploadAccum = 0; - Log.info("Upload: @ b/s", upload.mean()); + Log.info(, upload.mean()); } uploadAccum += byteBuffer.position() - lastPos; } @@ -640,7 +640,7 @@ public class ArcNetProvider implements NetProvider{ p.connectionID = buffer.getInt(); return p; }else{ - throw new RuntimeException("Unknown framework message!"); + throw new RuntimeException(); } } } @@ -704,7 +704,7 @@ public class Streamable extends Packet{ * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided + * particular file as subject to the exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT @@ -789,7 +789,7 @@ import jdk.internal.vm.annotation.Stable; * operations can produce a BigInteger with a different sign from the * BigInteger being operated on, as they affect only a single bit, and the * arbitrarily large abstraction provided by this class ensures that conceptually - * there are infinitely many "virtual sign bits" preceding each BigInteger. + * there are infinitely many preceding each BigInteger. * *

For the sake of brevity and clarity, pseudo-code is used throughout the * descriptions of BigInteger methods. The pseudo-code expression @@ -881,7 +881,7 @@ public class BigInteger extends Number implements Comparable { /** * The magnitude of this BigInteger, in big-endian order: the * zeroth element of this array is the most-significant int of the - * magnitude. The magnitude must be "minimal" in that the most-significant + * magnitude. The magnitude must be in that the most-significant * int ({@code mag[0]}) must be non-zero. This is necessary to * ensure that there is exactly one representation for each BigInteger * value. Note that this implies that the BigInteger zero has a @@ -1047,7 +1047,7 @@ public class BigInteger extends Number implements Comparable { */ public BigInteger(byte[] val, int off, int len) { if (val.length == 0) { - throw new NumberFormatException("Zero length BigInteger"); + throw new NumberFormatException(); } Objects.checkFromIndexSize(off, len, val.length); if (len == 0) { @@ -1094,7 +1094,7 @@ public class BigInteger extends Number implements Comparable { */ private BigInteger(int[] val) { if (val.length == 0) - throw new NumberFormatException("Zero length BigInteger"); + throw new NumberFormatException(); if (val[0] < 0) { mag = makePositive(val); @@ -1139,7 +1139,7 @@ public class BigInteger extends Number implements Comparable { */ public BigInteger(int signum, byte[] magnitude, int off, int len) { if (signum < -1 || signum > 1) { - throw(new NumberFormatException("Invalid signum value")); + throw(new NumberFormatException()); } Objects.checkFromIndexSize(off, len, magnitude.length); @@ -1150,7 +1150,7 @@ public class BigInteger extends Number implements Comparable { this.signum = 0; } else { if (signum == 0) - throw(new NumberFormatException("signum-magnitude mismatch")); + throw(new NumberFormatException()); this.signum = signum; } if (mag.length >= MAX_MAG_LENGTH) { @@ -1191,13 +1191,13 @@ public class BigInteger extends Number implements Comparable { this.mag = stripLeadingZeroInts(magnitude); if (signum < -1 || signum > 1) - throw(new NumberFormatException("Invalid signum value")); + throw(new NumberFormatException()); if (this.mag.length == 0) { this.signum = 0; } else { if (signum == 0) - throw(new NumberFormatException("signum-magnitude mismatch")); + throw(new NumberFormatException()); this.signum = signum; } if (mag.length >= MAX_MAG_LENGTH) { @@ -1227,9 +1227,9 @@ public class BigInteger extends Number implements Comparable { final int len = val.length(); if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) - throw new NumberFormatException("Radix out of range"); + throw new NumberFormatException(); if (len == 0) - throw new NumberFormatException("Zero length BigInteger"); + throw new NumberFormatException(); // Check for at most one leading sign int sign = 1; @@ -1237,18 +1237,18 @@ public class BigInteger extends Number implements Comparable { int index2 = val.lastIndexOf('+'); if (index1 >= 0) { if (index1 != 0 || index2 >= 0) { - throw new NumberFormatException("Illegal embedded sign character"); + throw new NumberFormatException(); } sign = -1; cursor = 1; } else if (index2 >= 0) { if (index2 != 0) { - throw new NumberFormatException("Illegal embedded sign character"); + throw new NumberFormatException(); } cursor = 1; } if (cursor == len) - throw new NumberFormatException("Zero length BigInteger"); + throw new NumberFormatException(); // Skip leading zeros and compute number of digits in magnitude while (cursor < len && @@ -1281,7 +1281,7 @@ public class BigInteger extends Number implements Comparable { String group = val.substring(cursor, cursor += firstGroupLen); magnitude[numWords - 1] = Integer.parseInt(group, radix); if (magnitude[numWords - 1] < 0) - throw new NumberFormatException("Illegal digit"); + throw new NumberFormatException(); // Process remaining digit groups int superRadix = intRadix[radix]; @@ -1290,7 +1290,7 @@ public class BigInteger extends Number implements Comparable { group = val.substring(cursor, cursor += digitsPerInt[radix]); groupVal = Integer.parseInt(group, radix); if (groupVal < 0) - throw new NumberFormatException("Illegal digit"); + throw new NumberFormatException(); destructiveMulAdd(magnitude, superRadix, groupVal); } // Required for cases where the array was overallocated. @@ -1455,7 +1455,7 @@ public class BigInteger extends Number implements Comparable { private static byte[] randomBits(int numBits, Random rnd) { if (numBits < 0) - throw new IllegalArgumentException("numBits must be non-negative"); + throw new IllegalArgumentException(); int numBytes = (int)(((long)numBits+7)/8); // avoid overflow byte[] randomBits = new byte[numBytes]; @@ -1491,7 +1491,7 @@ public class BigInteger extends Number implements Comparable { BigInteger prime; if (bitLength < 2) - throw new ArithmeticException("bitLength < 2"); + throw new ArithmeticException(); prime = (bitLength < SMALL_PRIME_THRESHOLD ? smallPrime(bitLength, certainty, rnd) : largePrime(bitLength, certainty, rnd)); @@ -1522,7 +1522,7 @@ public class BigInteger extends Number implements Comparable { */ public static BigInteger probablePrime(int bitLength, Random rnd) { if (bitLength < 2) - throw new ArithmeticException("bitLength < 2"); + throw new ArithmeticException(); return (bitLength < SMALL_PRIME_THRESHOLD ? smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) : @@ -1552,7 +1552,7 @@ public class BigInteger extends Number implements Comparable { BigInteger p = new BigInteger(temp, 1); - // Do cheap "pre-test" if applicable + // Do cheap if applicable if (bitLength > 6) { long r = p.remainder(SMALL_PRIME_PRODUCT).longValue(); if ((r%3==0) || (r%5==0) || (r%7==0) || (r%11==0) || @@ -1619,7 +1619,7 @@ public class BigInteger extends Number implements Comparable { */ public BigInteger nextProbablePrime() { if (this.signum < 0) - throw new ArithmeticException("start < 0: " + this); + throw new ArithmeticException( + this); // Handle trivial cases if ((this.signum == 0) || this.equals(ONE)) @@ -1635,7 +1635,7 @@ public class BigInteger extends Number implements Comparable { result = result.add(ONE); while (true) { - // Do cheap "pre-test" if applicable + // Do cheap if applicable if (result.bitLength() > 6) { long r = result.remainder(SMALL_PRIME_PRODUCT).longValue(); if ((r%3==0) || (r%5==0) || (r%7==0) || (r%11==0) || @@ -1677,7 +1677,7 @@ public class BigInteger extends Number implements Comparable { private static int getPrimeSearchLen(int bitLength) { if (bitLength > PRIME_SEARCH_BIT_LENGTH_LIMIT + 1) { - throw new ArithmeticException("Prime search implementation restriction on bitLength"); + throw new ArithmeticException(); } return bitLength / 20 * 64; } @@ -1916,7 +1916,7 @@ public class BigInteger extends Number implements Comparable { } private static void reportOverflow() { - throw new ArithmeticException("BigInteger would overflow supported range"); + throw new ArithmeticException(); } //Static Factory Methods @@ -2006,7 +2006,7 @@ public class BigInteger extends Number implements Comparable { && 0 < KARATSUBA_SQUARE_THRESHOLD && KARATSUBA_SQUARE_THRESHOLD < TOOM_COOK_SQUARE_THRESHOLD && TOOM_COOK_SQUARE_THRESHOLD < Integer.MAX_VALUE : - "Algorithm thresholds are inconsistent"; + ; for (int i = 1; i <= MAX_CONSTANT; i++) { int[] magnitude = new int[1]; @@ -2397,7 +2397,7 @@ public class BigInteger extends Number implements Comparable { return multiplyKaratsuba(this, val); } else { // - // In "Hacker's Delight" section 2-13, p.33, it is explained + // In section 2-13, p.33, it is explained // that if x and y are unsigned 32-bit quantities and m and n // are their respective numbers of leading zeros within 32 bits, // then the number of leading zeros within their product as a @@ -2415,7 +2415,7 @@ public class BigInteger extends Number implements Comparable { // == 31 x >= 64 - 32 = 32 possible overflow // <= 30 x >= 64 - 31 = 33 definite overflow // - // The "possible overflow" condition cannot be detected by + // The condition cannot be detected by // examning data lengths alone and requires further calculation. // // By analogy, if 'this' and 'val' have m and n as their @@ -2579,8 +2579,8 @@ public class BigInteger extends Number implements Comparable { * Multiplies two BigIntegers using the Karatsuba multiplication * algorithm. This is a recursive divide-and-conquer algorithm which is * more efficient for large numbers than what is commonly called the - * "grade-school" algorithm used in multiplyToLen. If the numbers to be - * multiplied have length n, the "grade-school" algorithm has an + * algorithm used in multiplyToLen. If the numbers to be + * multiplied have length n, the algorithm has an * asymptotic complexity of O(n^2). In contrast, the Karatsuba algorithm * has complexity of O(n^(log2(3))), or O(n^1.585). It achieves this * increased performance by doing 3 multiplies instead of 4 when @@ -2620,7 +2620,7 @@ public class BigInteger extends Number implements Comparable { } } - @SuppressWarnings("serial") + @SuppressWarnings() private abstract static sealed class RecursiveOp extends RecursiveTask { /** * The threshold until when we should continue forking recursive ops @@ -2661,7 +2661,7 @@ public class BigInteger extends Number implements Comparable { return this; } - @SuppressWarnings("serial") + @SuppressWarnings() private static final class RecursiveMultiply extends RecursiveOp { private final BigInteger a; private final BigInteger b; @@ -2678,7 +2678,7 @@ public class BigInteger extends Number implements Comparable { } } - @SuppressWarnings("serial") + @SuppressWarnings() private static final class RecursiveSquare extends RecursiveOp { private final BigInteger a; @@ -2706,8 +2706,8 @@ public class BigInteger extends Number implements Comparable { * Multiplies two BigIntegers using a 3-way Toom-Cook multiplication * algorithm. This is a recursive divide-and-conquer algorithm which is * more efficient for large numbers than what is commonly called the - * "grade-school" algorithm used in multiplyToLen. If the numbers to be - * multiplied have length n, the "grade-school" algorithm has an + * algorithm used in multiplyToLen. If the numbers to be + * multiplied have length n, the algorithm has an * asymptotic complexity of O(n^2). In contrast, 3-way Toom-Cook has a * complexity of about O(n^1.465). It achieves this increased asymptotic * performance by breaking each number into three parts and by doing 5 @@ -2718,7 +2718,7 @@ public class BigInteger extends Number implements Comparable { * than that for Karatsuba multiplication, so this algorithm is generally * only used when numbers become significantly larger. * - * The algorithm used is the "optimal" 3-way Toom-Cook algorithm outlined + * The algorithm used is the 3-way Toom-Cook algorithm outlined * by Marco Bodrato. * * See: http://bodrato.it/toom-cook/ @@ -2726,7 +2726,7 @@ public class BigInteger extends Number implements Comparable { * * "Towards Optimal Toom-Cook Multiplication for Univariate and * Multivariate Polynomials in Characteristic 2 and 0." by Marco BODRATO; - * In C.Carlet and B.Sunar, Eds., "WAIFI'07 proceedings", p. 116-133, + * In C.Carlet and B.Sunar, Eds., , p. 116-133, * LNCS #4547. Springer, Madrid, Spain, June 21-22, 2007. * */ @@ -2989,22 +2989,22 @@ public class BigInteger extends Number implements Comparable { */ private static void implSquareToLenChecks(int[] x, int len, int[] z, int zlen) throws RuntimeException { if (len < 1) { - throw new IllegalArgumentException("invalid input length: " + len); + throw new IllegalArgumentException( + len); } if (len > x.length) { - throw new IllegalArgumentException("input length out of bound: " + - len + " > " + x.length); + throw new IllegalArgumentException( + + len + + x.length); } if (len * 2 > z.length) { - throw new IllegalArgumentException("input length out of bound: " + - (len * 2) + " > " + z.length); + throw new IllegalArgumentException( + + (len * 2) + + z.length); } if (zlen < 1) { - throw new IllegalArgumentException("invalid input length: " + zlen); + throw new IllegalArgumentException( + zlen); } if (zlen > z.length) { - throw new IllegalArgumentException("input length out of bound: " + - len + " > " + z.length); + throw new IllegalArgumentException( + + len + + z.length); } } @@ -3016,7 +3016,7 @@ public class BigInteger extends Number implements Comparable { /* * The algorithm used here is adapted from Colin Plumb's C library. * Technique: Consider the partial products in the multiplication - * of "abcde" by itself: + * of by itself: * * a b c d e * * a b c d e @@ -3284,7 +3284,7 @@ public class BigInteger extends Number implements Comparable { */ public BigInteger pow(int exponent) { if (exponent < 0) { - throw new ArithmeticException("Negative exponent"); + throw new ArithmeticException(); } if (signum == 0) { return (exponent == 0 ? ONE : this); @@ -3417,7 +3417,7 @@ public class BigInteger extends Number implements Comparable { */ public BigInteger sqrt() { if (this.signum < 0) { - throw new ArithmeticException("Negative BigInteger"); + throw new ArithmeticException(); } return new MutableBigInteger(this.mag).sqrt().toBigInteger(); @@ -3571,7 +3571,7 @@ public class BigInteger extends Number implements Comparable { */ public BigInteger mod(BigInteger m) { if (m.signum <= 0) - throw new ArithmeticException("BigInteger: modulus not positive"); + throw new ArithmeticException(); BigInteger result = this.remainder(m); return (result.signum >= 0 ? result : result.add(m)); @@ -3592,7 +3592,7 @@ public class BigInteger extends Number implements Comparable { */ public BigInteger modPow(BigInteger exponent, BigInteger m) { if (m.signum <= 0) - throw new ArithmeticException("BigInteger: modulus not positive"); + throw new ArithmeticException(); // Trivial cases if (exponent.signum == 0) @@ -3618,7 +3618,7 @@ public class BigInteger extends Number implements Comparable { result = base.oddModPow(exponent, m); } else { /* - * Even modulus. Tear it into an "odd part" (m1) and power of two + * Even modulus. Tear it into an (m1) and power of two * (m2), exponentiate mod m1, manually exponentiate mod m2, and * use Chinese Remainder Theorem to combine results. */ @@ -3692,18 +3692,18 @@ public class BigInteger extends Number implements Comparable { private static void implMontgomeryMultiplyChecks (int[] a, int[] b, int[] n, int len, int[] product) throws RuntimeException { if (len % 2 != 0) { - throw new IllegalArgumentException("input array length must be even: " + len); + throw new IllegalArgumentException( + len); } if (len < 1) { - throw new IllegalArgumentException("invalid input length: " + len); + throw new IllegalArgumentException( + len); } if (len > a.length || len > b.length || len > n.length || (product != null && len > product.length)) { - throw new IllegalArgumentException("input array length out of bound: " + len); + throw new IllegalArgumentException( + len); } } @@ -3734,799 +3734,6 @@ public class BigInteger extends Number implements Comparable { static int[] bnExpModThreshTable = {7, 25, 81, 241, 673, 1793, Integer.MAX_VALUE}; // Sentinel - /** - * Returns a BigInteger whose value is x to the power of y mod z. - * Assumes: z is odd && x < z. - */ - private BigInteger oddModPow(BigInteger y, BigInteger z) { - /* - * The algorithm is adapted from Colin Plumb's C library. - * - * The window algorithm: - * The idea is to keep a running product of b1 = n^(high-order bits of exp) - * and then keep appending exponent bits to it. The following patterns - * apply to a 3-bit window (k = 3): - * To append 0: square - * To append 1: square, multiply by n^1 - * To append 10: square, multiply by n^1, square - * To append 11: square, square, multiply by n^3 - * To append 100: square, multiply by n^1, square, square - * To append 101: square, square, square, multiply by n^5 - * To append 110: square, square, multiply by n^3, square - * To append 111: square, square, square, multiply by n^7 - * - * Since each pattern involves only one multiply, the longer the pattern - * the better, except that a 0 (no multiplies) can be appended directly. - * We precompute a table of odd powers of n, up to 2^k, and can then - * multiply k bits of exponent at a time. Actually, assuming random - * exponents, there is on average one zero bit between needs to - * multiply (1/2 of the time there's none, 1/4 of the time there's 1, - * 1/8 of the time, there's 2, 1/32 of the time, there's 3, etc.), so - * you have to do one multiply per k+1 bits of exponent. - * - * The loop walks down the exponent, squaring the result buffer as - * it goes. There is a wbits+1 bit lookahead buffer, buf, that is - * filled with the upcoming exponent bits. (What is read after the - * end of the exponent is unimportant, but it is filled with zero here.) - * When the most-significant bit of this buffer becomes set, i.e. - * (buf & tblmask) != 0, we have to decide what pattern to multiply - * by, and when to do it. We decide, remember to do it in future - * after a suitable number of squarings have passed (e.g. a pattern - * of "100" in the buffer requires that we multiply by n^1 immediately; - * a pattern of "110" calls for multiplying by n^3 after one more - * squaring), clear the buffer, and continue. - * - * When we start, there is one more optimization: the result buffer - * is implcitly one, so squaring it or multiplying by it can be - * optimized away. Further, if we start with a pattern like "100" - * in the lookahead window, rather than placing n into the buffer - * and then starting to square it, we have already computed n^2 - * to compute the odd-powers table, so we can place that into - * the buffer and save a squaring. - * - * This means that if you have a k-bit window, to compute n^z, - * where z is the high k bits of the exponent, 1/2 of the time - * it requires no squarings. 1/4 of the time, it requires 1 - * squaring, ... 1/2^(k-1) of the time, it requires k-2 squarings. - * And the remaining 1/2^(k-1) of the time, the top k bits are a - * 1 followed by k-1 0 bits, so it again only requires k-2 - * squarings, not k-1. The average of these is 1. Add that - * to the one squaring we have to do to compute the table, - * and you'll see that a k-bit window saves k-2 squarings - * as well as reducing the multiplies. (It actually doesn't - * hurt in the case k = 1, either.) - */ - // Special case for exponent of one - if (y.equals(ONE)) - return this; - - // Special case for base of zero - if (signum == 0) - return ZERO; - - int[] base = mag.clone(); - int[] exp = y.mag; - int[] mod = z.mag; - int modLen = mod.length; - - // Make modLen even. It is conventional to use a cryptographic - // modulus that is 512, 768, 1024, or 2048 bits, so this code - // will not normally be executed. However, it is necessary for - // the correct functioning of the HotSpot intrinsics. - if ((modLen & 1) != 0) { - int[] x = new int[modLen + 1]; - System.arraycopy(mod, 0, x, 1, modLen); - mod = x; - modLen++; - } - - // Select an appropriate window size - int wbits = 0; - int ebits = bitLength(exp, exp.length); - // if exponent is 65537 (0x10001), use minimum window size - if ((ebits != 17) || (exp[0] != 65537)) { - while (ebits > bnExpModThreshTable[wbits]) { - wbits++; - } - } - - // Calculate appropriate table size - int tblmask = 1 << wbits; - - // Allocate table for precomputed odd powers of base in Montgomery form - int[][] table = new int[tblmask][]; - for (int i=0; i < tblmask; i++) - table[i] = new int[modLen]; - - // Compute the modular inverse of the least significant 64-bit - // digit of the modulus - long n0 = (mod[modLen-1] & LONG_MASK) + ((mod[modLen-2] & LONG_MASK) << 32); - long inv = -MutableBigInteger.inverseMod64(n0); - - // Convert base to Montgomery form - int[] a = leftShift(base, base.length, modLen << 5); - - MutableBigInteger q = new MutableBigInteger(), - a2 = new MutableBigInteger(a), - b2 = new MutableBigInteger(mod); - b2.normalize(); // MutableBigInteger.divide() assumes that its - // divisor is in normal form. - - MutableBigInteger r= a2.divide(b2, q); - table[0] = r.toIntArray(); - - // Pad table[0] with leading zeros so its length is at least modLen - if (table[0].length < modLen) { - int offset = modLen - table[0].length; - int[] t2 = new int[modLen]; - System.arraycopy(table[0], 0, t2, offset, table[0].length); - table[0] = t2; - } - - // Set b to the square of the base - int[] b = montgomerySquare(table[0], mod, modLen, inv, null); - - // Set t to high half of b - int[] t = Arrays.copyOf(b, modLen); - - // Fill in the table with odd powers of the base - for (int i=1; i < tblmask; i++) { - table[i] = montgomeryMultiply(t, table[i-1], mod, modLen, inv, null); - } - - // Pre load the window that slides over the exponent - int bitpos = 1 << ((ebits-1) & (32-1)); - - int buf = 0; - int elen = exp.length; - int eIndex = 0; - for (int i = 0; i <= wbits; i++) { - buf = (buf << 1) | (((exp[eIndex] & bitpos) != 0)?1:0); - bitpos >>>= 1; - if (bitpos == 0) { - eIndex++; - bitpos = 1 << (32-1); - elen--; - } - } - - int multpos = ebits; - - // The first iteration, which is hoisted out of the main loop - ebits--; - boolean isone = true; - - multpos = ebits - wbits; - while ((buf & 1) == 0) { - buf >>>= 1; - multpos++; - } - - int[] mult = table[buf >>> 1]; - - buf = 0; - if (multpos == ebits) - isone = false; - - // The main loop - while (true) { - ebits--; - // Advance the window - buf <<= 1; - - if (elen != 0) { - buf |= ((exp[eIndex] & bitpos) != 0) ? 1 : 0; - bitpos >>>= 1; - if (bitpos == 0) { - eIndex++; - bitpos = 1 << (32-1); - elen--; - } - } - - // Examine the window for pending multiplies - if ((buf & tblmask) != 0) { - multpos = ebits - wbits; - while ((buf & 1) == 0) { - buf >>>= 1; - multpos++; - } - mult = table[buf >>> 1]; - buf = 0; - } - - // Perform multiply - if (ebits == multpos) { - if (isone) { - b = mult.clone(); - isone = false; - } else { - t = b; - a = montgomeryMultiply(t, mult, mod, modLen, inv, a); - t = a; a = b; b = t; - } - } - - // Check if done - if (ebits == 0) - break; - - // Square the input - if (!isone) { - t = b; - a = montgomerySquare(t, mod, modLen, inv, a); - t = a; a = b; b = t; - } - } - - // Convert result out of Montgomery form and return - int[] t2 = new int[2*modLen]; - System.arraycopy(b, 0, t2, modLen, modLen); - - b = montReduce(t2, mod, modLen, (int)inv); - - t2 = Arrays.copyOf(b, modLen); - - return new BigInteger(1, t2); - } - - /** - * Montgomery reduce n, modulo mod. This reduces modulo mod and divides - * by 2^(32*mlen). Adapted from Colin Plumb's C library. - */ - private static int[] montReduce(int[] n, int[] mod, int mlen, int inv) { - int c=0; - int len = mlen; - int offset=0; - - do { - int nEnd = n[n.length-1-offset]; - int carry = mulAdd(n, mod, offset, mlen, inv * nEnd); - c += addOne(n, offset, mlen, carry); - offset++; - } while (--len > 0); - - while (c > 0) - c += subN(n, mod, mlen); - - while (intArrayCmpToLen(n, mod, mlen) >= 0) - subN(n, mod, mlen); - - return n; - } - - - /* - * Returns -1, 0 or +1 as big-endian unsigned int array arg1 is less than, - * equal to, or greater than arg2 up to length len. - */ - private static int intArrayCmpToLen(int[] arg1, int[] arg2, int len) { - for (int i=0; i < len; i++) { - long b1 = arg1[i] & LONG_MASK; - long b2 = arg2[i] & LONG_MASK; - if (b1 < b2) - return -1; - if (b1 > b2) - return 1; - } - return 0; - } - - /** - * Subtracts two numbers of same length, returning borrow. - */ - private static int subN(int[] a, int[] b, int len) { - long sum = 0; - - while (--len >= 0) { - sum = (a[len] & LONG_MASK) - - (b[len] & LONG_MASK) + (sum >> 32); - a[len] = (int)sum; - } - - return (int)(sum >> 32); - } - - /** - * Multiply an array by one word k and add to result, return the carry - */ - static int mulAdd(int[] out, int[] in, int offset, int len, int k) { - implMulAddCheck(out, in, offset, len, k); - return implMulAdd(out, in, offset, len, k); - } - - /** - * Parameters validation. - */ - private static void implMulAddCheck(int[] out, int[] in, int offset, int len, int k) { - if (len > in.length) { - throw new IllegalArgumentException("input length is out of bound: " + len + " > " + in.length); - } - if (offset < 0) { - throw new IllegalArgumentException("input offset is invalid: " + offset); - } - if (offset > (out.length - 1)) { - throw new IllegalArgumentException("input offset is out of bound: " + offset + " > " + (out.length - 1)); - } - if (len > (out.length - offset)) { - throw new IllegalArgumentException("input len is out of bound: " + len + " > " + (out.length - offset)); - } - } - - /** - * Java Runtime may use intrinsic for this method. - */ - @IntrinsicCandidate - private static int implMulAdd(int[] out, int[] in, int offset, int len, int k) { - long kLong = k & LONG_MASK; - long carry = 0; - - offset = out.length-offset - 1; - for (int j=len-1; j >= 0; j--) { - long product = (in[j] & LONG_MASK) * kLong + - (out[offset] & LONG_MASK) + carry; - out[offset--] = (int)product; - carry = product >>> 32; - } - return (int)carry; - } - - /** - * Add one word to the number a mlen words into a. Return the resulting - * carry. - */ - static int addOne(int[] a, int offset, int mlen, int carry) { - offset = a.length-1-mlen-offset; - long t = (a[offset] & LONG_MASK) + (carry & LONG_MASK); - - a[offset] = (int)t; - if ((t >>> 32) == 0) - return 0; - while (--mlen >= 0) { - if (--offset < 0) { // Carry out of number - return 1; - } else { - a[offset]++; - if (a[offset] != 0) - return 0; - } - } - return 1; - } - - /** - * Returns a BigInteger whose value is (this ** exponent) mod (2**p) - */ - private BigInteger modPow2(BigInteger exponent, int p) { - /* - * Perform exponentiation using repeated squaring trick, chopping off - * high order bits as indicated by modulus. - */ - BigInteger result = ONE; - BigInteger baseToPow2 = this.mod2(p); - int expOffset = 0; - - int limit = exponent.bitLength(); - - if (this.testBit(0)) - limit = (p-1) < limit ? (p-1) : limit; - - while (expOffset < limit) { - if (exponent.testBit(expOffset)) - result = result.multiply(baseToPow2).mod2(p); - expOffset++; - if (expOffset < limit) - baseToPow2 = baseToPow2.square().mod2(p); - } - - return result; - } - - /** - * Returns a BigInteger whose value is this mod(2**p). - * Assumes that this {@code BigInteger >= 0} and {@code p > 0}. - */ - private BigInteger mod2(int p) { - if (bitLength() <= p) - return this; - - // Copy remaining ints of mag - int numInts = (p + 31) >>> 5; - int[] mag = new int[numInts]; - System.arraycopy(this.mag, (this.mag.length - numInts), mag, 0, numInts); - - // Mask out any excess bits - int excessBits = (numInts << 5) - p; - mag[0] &= (int)((1L << (32-excessBits)) - 1); - - return (mag[0] == 0 ? new BigInteger(1, mag) : new BigInteger(mag, 1)); - } - - /** - * Returns a BigInteger whose value is {@code (this}-1 {@code mod m)}. - * - * @param m the modulus. - * @return {@code this}-1 {@code mod m}. - * @throws ArithmeticException {@code m} ≤ 0, or this BigInteger - * has no multiplicative inverse mod m (that is, this BigInteger - * is not relatively prime to m). - */ - public BigInteger modInverse(BigInteger m) { - if (m.signum != 1) - throw new ArithmeticException("BigInteger: modulus not positive"); - - if (m.equals(ONE)) - return ZERO; - - // Calculate (this mod m) - BigInteger modVal = this; - if (signum < 0 || (this.compareMagnitude(m) >= 0)) - modVal = this.mod(m); - - if (modVal.equals(ONE)) - return ONE; - - MutableBigInteger a = new MutableBigInteger(modVal); - MutableBigInteger b = new MutableBigInteger(m); - - MutableBigInteger result = a.mutableModInverse(b); - return result.toBigInteger(1); - } - - // Shift Operations - - /** - * Returns a BigInteger whose value is {@code (this << n)}. - * The shift distance, {@code n}, may be negative, in which case - * this method performs a right shift. - * (Computes floor(this * 2n).) - * - * @param n shift distance, in bits. - * @return {@code this << n} - * @see #shiftRight - */ - public BigInteger shiftLeft(int n) { - if (signum == 0) - return ZERO; - if (n > 0) { - return new BigInteger(shiftLeft(mag, n), signum); - } else if (n == 0) { - return this; - } else { - // Possible int overflow in (-n) is not a trouble, - // because shiftRightImpl considers its argument unsigned - return shiftRightImpl(-n); - } - } - - /** - * Returns a magnitude array whose value is {@code (mag << n)}. - * The shift distance, {@code n}, is considered unnsigned. - * (Computes this * 2n.) - * - * @param mag magnitude, the most-significant int ({@code mag[0]}) must be non-zero. - * @param n unsigned shift distance, in bits. - * @return {@code mag << n} - */ - private static int[] shiftLeft(int[] mag, int n) { - int nInts = n >>> 5; - int nBits = n & 0x1f; - int magLen = mag.length; - int newMag[] = null; - - if (nBits == 0) { - newMag = new int[magLen + nInts]; - System.arraycopy(mag, 0, newMag, 0, magLen); - } else { - int i = 0; - int nBits2 = 32 - nBits; - int highBits = mag[0] >>> nBits2; - if (highBits != 0) { - newMag = new int[magLen + nInts + 1]; - newMag[i++] = highBits; - } else { - newMag = new int[magLen + nInts]; - } - int numIter = magLen - 1; - Objects.checkFromToIndex(0, numIter + 1, mag.length); - Objects.checkFromToIndex(i, numIter + i + 1, newMag.length); - shiftLeftImplWorker(newMag, mag, i, nBits, numIter); - newMag[numIter + i] = mag[numIter] << nBits; - } - return newMag; - } - - @ForceInline - @IntrinsicCandidate - private static void shiftLeftImplWorker(int[] newArr, int[] oldArr, int newIdx, int shiftCount, int numIter) { - int shiftCountRight = 32 - shiftCount; - int oldIdx = 0; - while (oldIdx < numIter) { - newArr[newIdx++] = (oldArr[oldIdx++] << shiftCount) | (oldArr[oldIdx] >>> shiftCountRight); - } - } - - /** - * Returns a BigInteger whose value is {@code (this >> n)}. Sign - * extension is performed. The shift distance, {@code n}, may be - * negative, in which case this method performs a left shift. - * (Computes floor(this / 2n).) - * - * @param n shift distance, in bits. - * @return {@code this >> n} - * @see #shiftLeft - */ - public BigInteger shiftRight(int n) { - if (signum == 0) - return ZERO; - if (n > 0) { - return shiftRightImpl(n); - } else if (n == 0) { - return this; - } else { - // Possible int overflow in {@code -n} is not a trouble, - // because shiftLeft considers its argument unsigned - return new BigInteger(shiftLeft(mag, -n), signum); - } - } - - /** - * Returns a BigInteger whose value is {@code (this >> n)}. The shift - * distance, {@code n}, is considered unsigned. - * (Computes floor(this * 2-n).) - * - * @param n unsigned shift distance, in bits. - * @return {@code this >> n} - */ - private BigInteger shiftRightImpl(int n) { - int nInts = n >>> 5; - int nBits = n & 0x1f; - int magLen = mag.length; - int newMag[] = null; - - // Special case: entire contents shifted off the end - if (nInts >= magLen) - return (signum >= 0 ? ZERO : negConst[1]); - - if (nBits == 0) { - int newMagLen = magLen - nInts; - newMag = Arrays.copyOf(mag, newMagLen); - } else { - int i = 0; - int highBits = mag[0] >>> nBits; - if (highBits != 0) { - newMag = new int[magLen - nInts]; - newMag[i++] = highBits; - } else { - newMag = new int[magLen - nInts -1]; - } - int numIter = magLen - nInts - 1; - Objects.checkFromToIndex(0, numIter + 1, mag.length); - Objects.checkFromToIndex(i, numIter + i, newMag.length); - shiftRightImplWorker(newMag, mag, i, nBits, numIter); - } - - if (signum < 0) { - // Find out whether any one-bits were shifted off the end. - boolean onesLost = false; - for (int i=magLen-1, j=magLen-nInts; i >= j && !onesLost; i--) - onesLost = (mag[i] != 0); - if (!onesLost && nBits != 0) - onesLost = (mag[magLen - nInts - 1] << (32 - nBits) != 0); - - if (onesLost) - newMag = javaIncrement(newMag); - } - - return new BigInteger(newMag, signum); - } - - @ForceInline - @IntrinsicCandidate - private static void shiftRightImplWorker(int[] newArr, int[] oldArr, int newIdx, int shiftCount, int numIter) { - int shiftCountLeft = 32 - shiftCount; - int idx = numIter; - int nidx = (newIdx == 0) ? numIter - 1 : numIter; - while (nidx >= newIdx) { - newArr[nidx--] = (oldArr[idx--] >>> shiftCount) | (oldArr[idx] << shiftCountLeft); - } - } - - int[] javaIncrement(int[] val) { - int lastSum = 0; - for (int i=val.length-1; i >= 0 && lastSum == 0; i--) - lastSum = (val[i] += 1); - if (lastSum == 0) { - val = new int[val.length+1]; - val[0] = 1; - } - return val; - } - - // Bitwise Operations - - /** - * Returns a BigInteger whose value is {@code (this & val)}. (This - * method returns a negative BigInteger if and only if this and val are - * both negative.) - * - * @param val value to be AND'ed with this BigInteger. - * @return {@code this & val} - */ - public BigInteger and(BigInteger val) { - int[] result = new int[Math.max(intLength(), val.intLength())]; - for (int i=0; i < result.length; i++) - result[i] = (getInt(result.length-i-1) - & val.getInt(result.length-i-1)); - - return valueOf(result); - } - - /** - * Returns a BigInteger whose value is {@code (this | val)}. (This method - * returns a negative BigInteger if and only if either this or val is - * negative.) - * - * @param val value to be OR'ed with this BigInteger. - * @return {@code this | val} - */ - public BigInteger or(BigInteger val) { - int[] result = new int[Math.max(intLength(), val.intLength())]; - for (int i=0; i < result.length; i++) - result[i] = (getInt(result.length-i-1) - | val.getInt(result.length-i-1)); - - return valueOf(result); - } - - /** - * Returns a BigInteger whose value is {@code (this ^ val)}. (This method - * returns a negative BigInteger if and only if exactly one of this and - * val are negative.) - * - * @param val value to be XOR'ed with this BigInteger. - * @return {@code this ^ val} - */ - public BigInteger xor(BigInteger val) { - int[] result = new int[Math.max(intLength(), val.intLength())]; - for (int i=0; i < result.length; i++) - result[i] = (getInt(result.length-i-1) - ^ val.getInt(result.length-i-1)); - - return valueOf(result); - } - - /** - * Returns a BigInteger whose value is {@code (~this)}. (This method - * returns a negative value if and only if this BigInteger is - * non-negative.) - * - * @return {@code ~this} - */ - public BigInteger not() { - int[] result = new int[intLength()]; - for (int i=0; i < result.length; i++) - result[i] = ~getInt(result.length-i-1); - - return valueOf(result); - } - - /** - * Returns a BigInteger whose value is {@code (this & ~val)}. This - * method, which is equivalent to {@code and(val.not())}, is provided as - * a convenience for masking operations. (This method returns a negative - * BigInteger if and only if {@code this} is negative and {@code val} is - * positive.) - * - * @param val value to be complemented and AND'ed with this BigInteger. - * @return {@code this & ~val} - */ - public BigInteger andNot(BigInteger val) { - int[] result = new int[Math.max(intLength(), val.intLength())]; - for (int i=0; i < result.length; i++) - result[i] = (getInt(result.length-i-1) - & ~val.getInt(result.length-i-1)); - - return valueOf(result); - } - - - // Single Bit Operations - - /** - * Returns {@code true} if and only if the designated bit is set. - * (Computes {@code ((this & (1<>> 5) & (1 << (n & 31))) != 0; - } - - /** - * Returns a BigInteger whose value is equivalent to this BigInteger - * with the designated bit set. (Computes {@code (this | (1<>> 5; - int[] result = new int[Math.max(intLength(), intNum+2)]; - - for (int i=0; i < result.length; i++) - result[result.length-i-1] = getInt(i); - - result[result.length-intNum-1] |= (1 << (n & 31)); - - return valueOf(result); - } - - /** - * Returns a BigInteger whose value is equivalent to this BigInteger - * with the designated bit cleared. - * (Computes {@code (this & ~(1<>> 5; - int[] result = new int[Math.max(intLength(), ((n + 1) >>> 5) + 1)]; - - for (int i=0; i < result.length; i++) - result[result.length-i-1] = getInt(i); - - result[result.length-intNum-1] &= ~(1 << (n & 31)); - - return valueOf(result); - } - - /** - * Returns a BigInteger whose value is equivalent to this BigInteger - * with the designated bit flipped. - * (Computes {@code (this ^ (1<>> 5; - int[] result = new int[Math.max(intLength(), intNum+2)]; - - for (int i=0; i < result.length; i++) - result[result.length-i-1] = getInt(i); - - result[result.length-intNum-1] ^= (1 << (n & 31)); - - return valueOf(result); - } - - /** - * Returns the index of the rightmost (lowest-order) one bit in this - * BigInteger (the number of zero bits to the right of the rightmost - * one bit). Returns -1 if this BigInteger contains no one bits. - * (Computes {@code (this == 0? -1 : log2(this & -this))}.) - * - * @return index of the rightmost one bit in this BigInteger. - */ public int getLowestSetBit() { int lsb = lowestSetBitPlusTwo - 2; if (lsb == -2) { // lowestSetBit not initialized yet @@ -4642,7 +3849,7 @@ public class BigInteger extends Number implements Comparable { if (!w.testBit(0) || w.equals(ONE)) return false; if (w.bitLength() > PRIME_SEARCH_BIT_LENGTH_LIMIT + 1) { - throw new ArithmeticException("Primality test implementation restriction on bitLength"); + throw new ArithmeticException(); } return w.primeToCertainty(certainty, null); } @@ -4831,7 +4038,7 @@ public class BigInteger extends Number implements Comparable { */ public String toString(int radix) { if (signum == 0) - return "0"; + return ; if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) radix = 10; @@ -5009,7 +4216,7 @@ public class BigInteger extends Number implements Comparable { private static int NUM_ZEROS = 63; /* ZEROS is a string of NUM_ZEROS consecutive zeros. */ - private static final String ZEROS = "0".repeat(NUM_ZEROS); + private static final String ZEROS = .repeat(NUM_ZEROS); /** * Returns the decimal String representation of this BigInteger. @@ -5135,7 +4342,7 @@ public class BigInteger extends Number implements Comparable { } /* - * We need the top SIGNIFICAND_WIDTH bits, including the "implicit" + * We need the top SIGNIFICAND_WIDTH bits, including the * one bit. To make rounding easier, we pick out the top * SIGNIFICAND_WIDTH + 1 bits, so we have one to help us round up or * down. twiceSignifFloor will contain the top SIGNIFICAND_WIDTH + 1 @@ -5220,7 +4427,7 @@ public class BigInteger extends Number implements Comparable { } /* - * We need the top SIGNIFICAND_WIDTH bits, including the "implicit" + * We need the top SIGNIFICAND_WIDTH bits, including the * one bit. To make rounding easier, we pick out the top * SIGNIFICAND_WIDTH + 1 bits, so we have one to help us round up or * down. twiceSignifFloor will contain the top SIGNIFICAND_WIDTH + 1 @@ -5316,7 +4523,7 @@ public class BigInteger extends Number implements Comparable { /* * Returns a copy of the input array stripped of any leading zero bytes. * The returned array is either empty, or its 0-th element is non-zero, - * meeting the "minimal" requirement for field mag (see comment on mag). + * meeting the requirement for field mag (see comment on mag). * * The range [from, from + len) must be well-formed w.r.t. array a. * @@ -5359,7 +4566,7 @@ public class BigInteger extends Number implements Comparable { */ int[] res = new int[((to - from) >> 2) + 1]; /* - * A "digit" is a group of 4 adjacent bytes aligned w.r.t. index to. + * A is a group of 4 adjacent bytes aligned w.r.t. index to. * (Implied 0 bytes are prepended as needed.) * b is the most significant byte not 0. * Digit d0 spans the range of indices that includes current (from - 1). @@ -5411,7 +4618,7 @@ public class BigInteger extends Number implements Comparable { for (; b == -1 && from < to; b = a[from++]) ; //empty body /* - * A "digit" is a group of 4 adjacent bytes aligned w.r.t. index to. + * A is a group of 4 adjacent bytes aligned w.r.t. index to. * b is the most significant byte not -1, or -1 only if from == to. * Digit d0 spans the range of indices that includes current (from - 1). * (Implied -1 bytes are prepended to array a as needed.) @@ -5505,9 +4712,9 @@ public class BigInteger extends Number implements Comparable { /* * The following two arrays are used for fast String conversions. Both * are indexed by radix. The first is the number of digits of the given - * radix that can fit in a Java long without "going negative", i.e., the + * radix that can fit in a Java long without , i.e., the * highest integer n such that radix**n < 2**63. The second is the - * "long radix" that tears each number into "long digits", each of which + * , each of which * consists of the number of digits in the corresponding element in * digitsPerLong (longRadix[i] = i**digitPerLong[i]). Both arrays have * nonsense values in their 0 and 1 elements, as radixes 0 and 1 are not @@ -5639,12 +4846,12 @@ public class BigInteger extends Number implements Comparable { */ @java.io.Serial private static final ObjectStreamField[] serialPersistentFields = { - new ObjectStreamField("signum", Integer.TYPE), - new ObjectStreamField("magnitude", byte[].class), - new ObjectStreamField("bitCount", Integer.TYPE), - new ObjectStreamField("bitLength", Integer.TYPE), - new ObjectStreamField("firstNonzeroByteNum", Integer.TYPE), - new ObjectStreamField("lowestSetBit", Integer.TYPE) + new ObjectStreamField(, Integer.TYPE), + new ObjectStreamField(, byte[].class), + new ObjectStreamField(, Integer.TYPE), + new ObjectStreamField(, Integer.TYPE), + new ObjectStreamField(, Integer.TYPE), + new ObjectStreamField(, Integer.TYPE) }; /** @@ -5673,22 +4880,22 @@ public class BigInteger extends Number implements Comparable { // care about, signum and magnitude // Read and validate signum - int sign = fields.get("signum", -2); + int sign = fields.get(, -2); if (sign < -1 || sign > 1) { - String message = "BigInteger: Invalid signum value"; - if (fields.defaulted("signum")) - message = "BigInteger: Signum not present in stream"; + String message = ; + if (fields.defaulted()) + message = ; throw new java.io.StreamCorruptedException(message); } // Read and validate magnitude - byte[] magnitude = (byte[])fields.get("magnitude", null); + byte[] magnitude = (byte[])fields.get(, null); magnitude = magnitude.clone(); // defensive copy int[] mag = stripLeadingZeroBytes(magnitude, 0, magnitude.length); if ((mag.length == 0) != (sign == 0)) { - String message = "BigInteger: signum-magnitude mismatch"; - if (fields.defaulted("magnitude")) - message = "BigInteger: Magnitude not present in stream"; + String message = ; + if (fields.defaulted()) + message = ; throw new java.io.StreamCorruptedException(message); } @@ -5696,7 +4903,7 @@ public class BigInteger extends Number implements Comparable { // this.mag field if (mag.length > MAX_MAG_LENGTH || (mag.length == MAX_MAG_LENGTH && mag[0] < 0)) { - throw new java.io.StreamCorruptedException("BigInteger: Out of the supported range"); + throw new java.io.StreamCorruptedException(); } // Commit final fields via Unsafe @@ -5709,7 +4916,7 @@ public class BigInteger extends Number implements Comparable { @java.io.Serial private void readObjectNoData() throws ObjectStreamException { - throw new InvalidObjectException("Deserialized BigInteger objects need data"); + throw new InvalidObjectException(); } // Support for resetting final fields while deserializing @@ -5717,9 +4924,9 @@ public class BigInteger extends Number implements Comparable { private static final jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); private static final long signumOffset - = unsafe.objectFieldOffset(BigInteger.class, "signum"); + = unsafe.objectFieldOffset(BigInteger.class, ); private static final long magOffset - = unsafe.objectFieldOffset(BigInteger.class, "mag"); + = unsafe.objectFieldOffset(BigInteger.class, ); static void putSignAndMag(BigInteger bi, int sign, int[] magnitude) { unsafe.putInt(bi, signumOffset, sign); @@ -5744,14 +4951,14 @@ public class BigInteger extends Number implements Comparable { private void writeObject(ObjectOutputStream s) throws IOException { // set the values of the Serializable fields ObjectOutputStream.PutField fields = s.putFields(); - fields.put("signum", signum); - fields.put("magnitude", magSerializedForm()); + fields.put(, signum); + fields.put(, magSerializedForm()); // The values written for cached fields are compatible with older // versions, but are ignored in readObject so don't otherwise matter. - fields.put("bitCount", -1); - fields.put("bitLength", -1); - fields.put("lowestSetBit", -2); - fields.put("firstNonzeroByteNum", -2); + fields.put(, -1); + fields.put(, -1); + fields.put(, -2); + fields.put(, -2); // save them s.writeFields(); @@ -5797,7 +5004,7 @@ public class BigInteger extends Number implements Comparable { if (mag.length <= 2 && bitLength() <= 63) return longValue(); else - throw new ArithmeticException("BigInteger out of long range"); + throw new ArithmeticException(); } /** @@ -5816,7 +5023,7 @@ public class BigInteger extends Number implements Comparable { if (mag.length <= 1 && bitLength() <= 31) return intValue(); else - throw new ArithmeticException("BigInteger out of int range"); + throw new ArithmeticException(); } /** @@ -5837,7 +5044,7 @@ public class BigInteger extends Number implements Comparable { if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) return shortValue(); } - throw new ArithmeticException("BigInteger out of short range"); + throw new ArithmeticException(); } /** @@ -5858,7 +5065,7 @@ public class BigInteger extends Number implements Comparable { if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) return byteValue(); } - throw new ArithmeticException("BigInteger out of byte range"); + throw new ArithmeticException(); } } @@ -5870,7 +5077,7 @@ public class BigInteger extends Number implements Comparable { * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided + * particular file as subject to the exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT @@ -5935,15 +5142,15 @@ import sun.reflect.misc.ReflectUtil; * loaded in this Java VM can be found/created using the lookup method. * *

The algorithm to compute the SerialVersionUID is described in - * - * Java Object Serialization Specification, Section 4.6, "Stream Unique Identifiers". + * + * Java Object Serialization Specification, Section 4.6, . * * @spec serialization/index.html Java Object Serialization Specification * @author Mike Warres * @author Roger Riggs * @see ObjectStreamField - * @see - * Java Object Serialization Specification, Section 4, "Class Descriptors" + * @see + * Java Object Serialization Specification, Section 4, * @since 1.1 */ public final class ObjectStreamClass implements Serializable { @@ -5962,7 +5169,7 @@ public final class ObjectStreamClass implements Serializable { NO_FIELDS; /** reflection factory for obtaining serialization constructors */ - @SuppressWarnings("removal") + @SuppressWarnings() private static final ReflectionFactory reflFactory = AccessController.doPrivileged( new ReflectionFactory.GetReflectionFactoryAction()); @@ -6143,7 +5350,7 @@ public final class ObjectStreamClass implements Serializable { * * @return the SUID of the class described by this descriptor */ - @SuppressWarnings("removal") + @SuppressWarnings() public long getSerialVersionUID() { // REMIND: synchronize instead of relying on volatile? if (suid == null) { @@ -6167,7 +5374,7 @@ public final class ObjectStreamClass implements Serializable { * * @return the {@code Class} instance that this descriptor represents */ - @SuppressWarnings("removal") + @SuppressWarnings() @CallerSensitive public Class forClass() { if (cl == null) { @@ -6210,13 +5417,13 @@ public final class ObjectStreamClass implements Serializable { * Return a string describing this ObjectStreamClass. */ public String toString() { - return name + ": static final long serialVersionUID = " + - getSerialVersionUID() + "L;"; + return name + + + getSerialVersionUID() + ; } /** * Looks up and returns class descriptor for given class, or null if class - * is non-serializable and "all" is set to false. + * is non-serializable and is set to false. * * @param cl class to look up * @param all if true, return descriptors for all classes; if false, only @@ -6232,7 +5439,7 @@ public final class ObjectStreamClass implements Serializable { /** * Creates local class descriptor representing given class. */ - @SuppressWarnings("removal") + @SuppressWarnings() private ObjectStreamClass(final Class cl) { this.cl = cl; name = cl.getName(); @@ -6276,21 +5483,21 @@ public final class ObjectStreamClass implements Serializable { cons = getExternalizableConstructor(cl); } else { cons = getSerializableConstructor(cl); - writeObjectMethod = getPrivateMethod(cl, "writeObject", + writeObjectMethod = getPrivateMethod(cl, , new Class[] { ObjectOutputStream.class }, Void.TYPE); - readObjectMethod = getPrivateMethod(cl, "readObject", + readObjectMethod = getPrivateMethod(cl, , new Class[] { ObjectInputStream.class }, Void.TYPE); readObjectNoDataMethod = getPrivateMethod( - cl, "readObjectNoData", null, Void.TYPE); + cl, , null, Void.TYPE); hasWriteObjectData = (writeObjectMethod != null); } domains = getProtectionDomains(cons, cl); writeReplaceMethod = getInheritableMethod( - cl, "writeReplace", null, Object.class); + cl, , null, Object.class); readResolveMethod = getInheritableMethod( - cl, "readResolve", null, Object.class); + cl, , null, Object.class); return null; } }); @@ -6308,18 +5515,18 @@ public final class ObjectStreamClass implements Serializable { if (deserializeEx == null) { if (isEnum) { - deserializeEx = new ExceptionInfo(name, "enum type"); + deserializeEx = new ExceptionInfo(name, ); } else if (cons == null && !isRecord) { - deserializeEx = new ExceptionInfo(name, "no valid constructor"); + deserializeEx = new ExceptionInfo(name, ); } } if (isRecord && canonicalCtr == null) { - deserializeEx = new ExceptionInfo(name, "record canonical constructor not found"); + deserializeEx = new ExceptionInfo(name, ); } else { for (int i = 0; i < fields.length; i++) { if (fields[i].getField() == null) { defaultSerializeEx = new ExceptionInfo( - name, "unmatched serializable field(s) declared"); + name, ); } } } @@ -6360,7 +5567,7 @@ public final class ObjectStreamClass implements Serializable { * ProtectionDomain that separate the concrete class {@code cl} * from its ancestor's declaring {@code cons}, or {@code null}. */ - @SuppressWarnings("removal") + @SuppressWarnings() private ProtectionDomain[] getProtectionDomains(Constructor cons, Class cl) { ProtectionDomain[] domains = null; @@ -6406,7 +5613,7 @@ public final class ObjectStreamClass implements Serializable { osc = lookup(cl, true); if (!osc.isProxy) { throw new InvalidClassException( - "cannot bind proxy descriptor to a non-proxy class"); + ); } } this.cl = cl; @@ -6445,42 +5652,42 @@ public final class ObjectStreamClass implements Serializable { osc = lookup(cl, true); if (osc.isProxy) { throw new InvalidClassException( - "cannot bind non-proxy descriptor to a proxy class"); + ); } if (model.isEnum != osc.isEnum) { throw new InvalidClassException(model.isEnum ? - "cannot bind enum descriptor to a non-enum class" : - "cannot bind non-enum descriptor to an enum class"); + : + ); } if (model.serializable == osc.serializable && !cl.isArray() && !cl.isRecord() && suid != osc.getSerialVersionUID()) { throw new InvalidClassException(osc.name, - "local class incompatible: " + - "stream classdesc serialVersionUID = " + suid + - ", local class serialVersionUID = " + + + + + suid + + + osc.getSerialVersionUID()); } if (!classNamesEqual(model.name, osc.name)) { throw new InvalidClassException(osc.name, - "local class name incompatible with stream class " + - "name \"" + model.name + "\""); + + + ); } if (!model.isEnum) { if ((model.serializable == osc.serializable) && (model.externalizable != osc.externalizable)) { throw new InvalidClassException(osc.name, - "Serializable incompatible with Externalizable"); + ); } if ((model.serializable != osc.serializable) || (model.externalizable != osc.externalizable) || !(model.serializable || model.externalizable)) { deserializeEx = new ExceptionInfo( - osc.name, "class invalid for deserialization"); + osc.name, ); } } } @@ -6551,19 +5758,19 @@ public final class ObjectStreamClass implements Serializable { ((flags & ObjectStreamConstants.SC_SERIALIZABLE) != 0); if (externalizable && sflag) { throw new InvalidClassException( - name, "serializable and externalizable flags conflict"); + name, ); } serializable = externalizable || sflag; isEnum = ((flags & ObjectStreamConstants.SC_ENUM) != 0); if (isEnum && suid.longValue() != 0L) { throw new InvalidClassException(name, - "enum descriptor has non-zero serialVersionUID: " + suid); + + suid); } int numFields = in.readShort(); if (isEnum && numFields != 0) { throw new InvalidClassException(name, - "enum descriptor has non-zero field count: " + numFields); + + numFields); } fields = (numFields > 0) ? new ObjectStreamField[numFields] : NO_FIELDS; @@ -6576,7 +5783,7 @@ public final class ObjectStreamClass implements Serializable { fields[i] = new ObjectStreamField(fname, signature, false); } catch (RuntimeException e) { throw new InvalidClassException(name, - "invalid descriptor for field " + + + fname, e); } } @@ -6632,7 +5839,7 @@ public final class ObjectStreamClass implements Serializable { */ private final void requireInitialized() { if (!initialized) - throw new InternalError("Unexpected call when not initialized"); + throw new InternalError(); } /** @@ -6642,7 +5849,7 @@ public final class ObjectStreamClass implements Serializable { */ final void checkInitialized() throws InvalidClassException { if (!initialized) { - throw new InvalidClassException("Class descriptor should be initialized"); + throw new InvalidClassException(); } } @@ -6695,7 +5902,7 @@ public final class ObjectStreamClass implements Serializable { } /** - * Returns the "local" class descriptor for the class associated with this + * Returns the class descriptor for the class associated with this * class descriptor (i.e., the result of * ObjectStreamClass.lookup(this.forClass())) or null if there is no class * associated with this descriptor. @@ -6872,7 +6079,7 @@ public final class ObjectStreamClass implements Serializable { * class is non-serializable or if the appropriate no-arg constructor is * inaccessible/unavailable. */ - @SuppressWarnings("removal") + @SuppressWarnings() Object newInstance() throws InstantiationException, InvocationTargetException, UnsupportedOperationException @@ -7080,13 +6287,13 @@ public final class ObjectStreamClass implements Serializable { /** * Class representing the portion of an object's serialized form allotted - * to data described by a given class descriptor. If "hasData" is false, + * to data described by a given class descriptor. If is false, * the object's serialized form does not contain data associated with the * class descriptor. */ static class ClassDataSlot { - /** class descriptor "occupying" this slot */ + /** class descriptor this slot */ final ObjectStreamClass desc; /** true if serialized form includes data for this slot's descriptor */ final boolean hasData; @@ -7101,7 +6308,7 @@ public final class ObjectStreamClass implements Serializable { * Returns array of ClassDataSlot instances representing the data layout * (including superclass data) for serialized objects described by this * class descriptor. ClassDataSlots are ordered by inheritance with those - * containing "higher" superclasses appearing first. The final + * containing superclasses appearing first. The final * ClassDataSlot contains a reference to this descriptor. */ ClassDataSlot[] getClassDataLayout() throws InvalidClassException { @@ -7127,7 +6334,7 @@ public final class ObjectStreamClass implements Serializable { for (ObjectStreamClass d = this; d != null; d = d.superDesc) { if (oscNames.contains(d.name)) { - throw new InvalidClassException("Circular reference."); + throw new InvalidClassException(); } else { oscNames.add(d.name); } @@ -7142,7 +6349,7 @@ public final class ObjectStreamClass implements Serializable { } } - // add "no data" slot for each unmatched class below match + // add slot for each unmatched class below match if (match != null) { for (Class c = start; c != match; c = c.getSuperclass()) { slots.add(new ClassDataSlot( @@ -7155,7 +6362,7 @@ public final class ObjectStreamClass implements Serializable { slots.add(new ClassDataSlot(d.getVariantFor(match), true)); } - // add "no data" slot for any leftover unmatched classes + // add slot for any leftover unmatched classes for (Class c = start; c != end; c = c.getSuperclass()) { slots.add(new ClassDataSlot( ObjectStreamClass.lookup(c, true), false)); @@ -7267,7 +6474,7 @@ public final class ObjectStreamClass implements Serializable { if (firstObjIndex != -1 && firstObjIndex + numObjFields != fields.length) { - throw new InvalidClassException(name, "illegal field order"); + throw new InvalidClassException(name, ); } } @@ -7321,9 +6528,9 @@ public final class ObjectStreamClass implements Serializable { * the not found ( which should never happen for correctly generated record * classes ). */ - @SuppressWarnings("removal") + @SuppressWarnings() private static MethodHandle canonicalRecordCtr(Class cls) { - assert cls.isRecord() : "Expected record, got: " + cls; + assert cls.isRecord() : + cls; PrivilegedAction pa = () -> { Class[] paramTypes = Arrays.stream(cls.getRecordComponents()) .map(RecordComponent::getType) @@ -7454,7 +6661,7 @@ public final class ObjectStreamClass implements Serializable { } else if (th instanceof Error) { throw (Error) th; } else { - throw new IOException("unexpected exception type", th); + throw new IOException(, th); } } @@ -7490,12 +6697,12 @@ public final class ObjectStreamClass implements Serializable { /** * Returns serializable fields of given class as defined explicitly by a - * "serialPersistentFields" field, or null if no appropriate - * "serialPersistentFields" field is defined. Serializable fields backed + * field, or null if no appropriate + * field is defined. Serializable fields backed * by an actual field of the class are represented by ObjectStreamFields * with corresponding non-null Field objects. For compatibility with past - * releases, a "serialPersistentFields" field with a null value is - * considered equivalent to not declaring "serialPersistentFields". Throws + * releases, a field with a null value is + * considered equivalent to not declaring . Throws * InvalidClassException if the declared serializable fields are * invalid--e.g., if multiple fields share the same name. */ @@ -7504,7 +6711,7 @@ public final class ObjectStreamClass implements Serializable { { ObjectStreamField[] serialPersistentFields = null; try { - Field f = cl.getDeclaredField("serialPersistentFields"); + Field f = cl.getDeclaredField(); int mask = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL; if ((f.getModifiers() & mask) == mask) { f.setAccessible(true); @@ -7528,7 +6735,7 @@ public final class ObjectStreamClass implements Serializable { String fname = spf.getName(); if (fieldNames.contains(fname)) { throw new InvalidClassException( - "multiple serializable fields named " + fname); + + fname); } fieldNames.add(fname); @@ -7577,7 +6784,7 @@ public final class ObjectStreamClass implements Serializable { */ private static Long getDeclaredSUID(Class cl) { try { - Field f = cl.getDeclaredField("serialVersionUID"); + Field f = cl.getDeclaredField(); int mask = Modifier.STATIC | Modifier.FINAL; if ((f.getModifiers() & mask) == mask) { f.setAccessible(true); @@ -7662,9 +6869,9 @@ public final class ObjectStreamClass implements Serializable { } if (hasStaticInitializer(cl)) { - dout.writeUTF(""); + dout.writeUTF(); dout.writeInt(Modifier.STATIC); - dout.writeUTF("()V"); + dout.writeUTF(); } Constructor[] cons = cl.getDeclaredConstructors(); @@ -7685,7 +6892,7 @@ public final class ObjectStreamClass implements Serializable { Modifier.SYNCHRONIZED | Modifier.NATIVE | Modifier.ABSTRACT | Modifier.STRICT); if ((mods & Modifier.PRIVATE) == 0) { - dout.writeUTF(""); + dout.writeUTF(); dout.writeInt(mods); dout.writeUTF(sig.signature.replace('/', '.')); } @@ -7720,7 +6927,7 @@ public final class ObjectStreamClass implements Serializable { dout.flush(); - MessageDigest md = MessageDigest.getInstance("SHA"); + MessageDigest md = MessageDigest.getInstance(); byte[] hashBytes = md.digest(bout.toByteArray()); long hash = 0; for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) { @@ -7959,11 +7166,11 @@ public final class ObjectStreamClass implements Serializable { { Field f = fields[i].getField(); throw new ClassCastException( - "cannot assign instance of " + - val.getClass().getName() + " to field " + - f.getDeclaringClass().getName() + "." + - f.getName() + " of type " + - f.getType().getName() + " in instance of " + + + + val.getClass().getName() + + + f.getDeclaringClass().getName() + + + f.getName() + + + f.getType().getName() + + obj.getClass().getName()); } if (!dryRun) @@ -8075,7 +7282,7 @@ public final class ObjectStreamClass implements Serializable { f.getTypeCode() != lf.getTypeCode()) { throw new InvalidClassException(localDesc.name, - "incompatible types for field " + f.getName()); + + f.getName()); } if (lf.getField() != null) { m = new ObjectStreamField( @@ -8099,7 +7306,7 @@ public final class ObjectStreamClass implements Serializable { /** * A LRA cache of record deserialization constructors. */ - @SuppressWarnings("serial") + @SuppressWarnings() private static final class DeserializationConstructorsCache extends ConcurrentHashMap { @@ -8217,7 +7424,7 @@ public final class ObjectStreamClass implements Serializable { * and return * {@code Object} */ - @SuppressWarnings("removal") + @SuppressWarnings() static MethodHandle deserializationCtr(ObjectStreamClass desc) { // check the cached value 1st MethodHandle mh = desc.deserializationCtr; @@ -8298,13 +7505,13 @@ public final class ObjectStreamClass implements Serializable { Class fType = f.getField().getType(); if (!pType.isAssignableFrom(fType)) - throw new InternalError(fName + " unassignable, pType:" + pType + ", fType:" + fType); + throw new InternalError(fName + + fType); if (f.isPrimitive()) { // (byte[], int):fType MethodHandle mh = PRIM_VALUE_EXTRACTORS.get(fType); if (mh == null) { - throw new InternalError("Unexpected type: " + fType); + throw new InternalError( + fType); } // bind offset // (byte[], int):fType -> (byte[]):fType @@ -8346,16 +7553,16 @@ public final class ObjectStreamClass implements Serializable { try { PRIM_VALUE_EXTRACTORS = Map.of( byte.class, MethodHandles.arrayElementGetter(byte[].class), - short.class, lkp.findStatic(ByteArray.class, "getShort", MethodType.methodType(short.class, byte[].class, int.class)), - int.class, lkp.findStatic(ByteArray.class, "getInt", MethodType.methodType(int.class, byte[].class, int.class)), - long.class, lkp.findStatic(ByteArray.class, "getLong", MethodType.methodType(long.class, byte[].class, int.class)), - float.class, lkp.findStatic(ByteArray.class, "getFloat", MethodType.methodType(float.class, byte[].class, int.class)), - double.class, lkp.findStatic(ByteArray.class, "getDouble", MethodType.methodType(double.class, byte[].class, int.class)), - char.class, lkp.findStatic(ByteArray.class, "getChar", MethodType.methodType(char.class, byte[].class, int.class)), - boolean.class, lkp.findStatic(ByteArray.class, "getBoolean", MethodType.methodType(boolean.class, byte[].class, int.class)) + short.class, lkp.findStatic(ByteArray.class, , MethodType.methodType(short.class, byte[].class, int.class)), + int.class, lkp.findStatic(ByteArray.class, , MethodType.methodType(int.class, byte[].class, int.class)), + long.class, lkp.findStatic(ByteArray.class, , MethodType.methodType(long.class, byte[].class, int.class)), + float.class, lkp.findStatic(ByteArray.class, , MethodType.methodType(float.class, byte[].class, int.class)), + double.class, lkp.findStatic(ByteArray.class, , MethodType.methodType(double.class, byte[].class, int.class)), + char.class, lkp.findStatic(ByteArray.class, , MethodType.methodType(char.class, byte[].class, int.class)), + boolean.class, lkp.findStatic(ByteArray.class, , MethodType.methodType(boolean.class, byte[].class, int.class)) ); } catch (NoSuchMethodException | IllegalAccessException e) { - throw new InternalError("Can't lookup " + ByteArray.class.getName() + ".getXXX", e); + throw new InternalError(, e); } } } @@ -8368,7 +7575,7 @@ public final class ObjectStreamClass implements Serializable { * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided + * particular file as subject to the exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT @@ -8465,15 +7672,15 @@ final class NetMulticastSocket extends MulticastSocket { */ private synchronized void connectInternal(InetAddress address, int port) throws SocketException { if (port < 0 || port > 0xFFFF) { - throw new IllegalArgumentException("connect: " + port); + throw new IllegalArgumentException( + port); } if (address == null) { - throw new IllegalArgumentException("connect: null address"); + throw new IllegalArgumentException(); } - checkAddress(address, "connect"); + checkAddress(address, ); if (isClosed()) return; - @SuppressWarnings("removal") + @SuppressWarnings() SecurityManager security = System.getSecurityManager(); if (security != null) { if (address.isMulticastAddress()) { @@ -8485,7 +7692,7 @@ final class NetMulticastSocket extends MulticastSocket { } if (port == 0) { - throw new SocketException("Can't connect to port 0"); + throw new SocketException(); } if (!isBound()) bind(new InetSocketAddress(0)); @@ -8532,19 +7739,19 @@ final class NetMulticastSocket extends MulticastSocket { @Override public synchronized void bind(SocketAddress addr) throws SocketException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); if (isBound()) - throw new SocketException("already bound"); + throw new SocketException(); if (addr == null) addr = new InetSocketAddress(0); if (!(addr instanceof InetSocketAddress epoint)) - throw new IllegalArgumentException("Unsupported address type!"); + throw new IllegalArgumentException(); if (epoint.isUnresolved()) - throw new SocketException("Unresolved address"); + throw new SocketException(); InetAddress iaddr = epoint.getAddress(); int port = epoint.getPort(); - checkAddress(iaddr, "bind"); - @SuppressWarnings("removal") + checkAddress(iaddr, ); + @SuppressWarnings() SecurityManager sec = System.getSecurityManager(); if (sec != null) { sec.checkListen(port); @@ -8563,7 +7770,7 @@ final class NetMulticastSocket extends MulticastSocket { return; } if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) { - throw new IllegalArgumentException(op + ": invalid address type"); + throw new IllegalArgumentException(op + ); } } @@ -8572,18 +7779,18 @@ final class NetMulticastSocket extends MulticastSocket { try { connectInternal(address, port); } catch (SocketException se) { - throw new UncheckedIOException("connect failed", se); + throw new UncheckedIOException(, se); } } @Override public void connect(SocketAddress addr) throws SocketException { if (addr == null) - throw new IllegalArgumentException("Address can't be null"); + throw new IllegalArgumentException(); if (!(addr instanceof InetSocketAddress epoint)) - throw new IllegalArgumentException("Unsupported address type"); + throw new IllegalArgumentException(); if (epoint.isUnresolved()) - throw new SocketException("Unresolved address"); + throw new SocketException(); connectInternal(epoint.getAddress(), epoint.getPort()); } @@ -8642,18 +7849,18 @@ final class NetMulticastSocket extends MulticastSocket { public void send(DatagramPacket p) throws IOException { synchronized (p) { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); InetAddress packetAddress = p.getAddress(); int packetPort = p.getPort(); - checkAddress(packetAddress, "send"); + checkAddress(packetAddress, ); if (connectState == ST_NOT_CONNECTED) { if (packetAddress == null) { - throw new IllegalArgumentException("Address not set"); + throw new IllegalArgumentException(); } if (packetPort < 0 || packetPort > 0xFFFF) - throw new IllegalArgumentException("port out of range: " + packetPort); + throw new IllegalArgumentException( + packetPort); // check the address is ok with the security manager on every send. - @SuppressWarnings("removal") + @SuppressWarnings() SecurityManager security = System.getSecurityManager(); // The reason you want to synchronize on datagram packet @@ -8669,7 +7876,7 @@ final class NetMulticastSocket extends MulticastSocket { } } if (packetPort == 0) { - throw new SocketException("Can't send to port 0"); + throw new SocketException(); } } else { // we're connected @@ -8678,9 +7885,9 @@ final class NetMulticastSocket extends MulticastSocket { p.setPort(connectedPort); } else if ((!packetAddress.equals(connectedAddress)) || packetPort != connectedPort) { - throw new IllegalArgumentException("connected address " + - "and packet address" + - " differ"); + throw new IllegalArgumentException( + + + + ); } } // Check whether the socket is bound @@ -8698,7 +7905,7 @@ final class NetMulticastSocket extends MulticastSocket { bind(new InetSocketAddress(0)); if (connectState == ST_NOT_CONNECTED) { // check the address is ok with the security manager before every recv. - @SuppressWarnings("removal") + @SuppressWarnings() SecurityManager security = System.getSecurityManager(); if (security != null) { while (true) { @@ -8733,7 +7940,7 @@ final class NetMulticastSocket extends MulticastSocket { if (explicitFilter) { // We have to do the filtering the old fashioned way since // the native impl doesn't support connect or the connect - // via the impl failed, or .. "explicitFilter" may be set when + // via the impl failed, or .. may be set when // a socket is connected via the impl, for a period of time // when packets from other sources might be queued on socket. boolean stop = false; @@ -8786,13 +7993,13 @@ final class NetMulticastSocket extends MulticastSocket { if (in.isAnyLocalAddress()) { in = InetAddress.anyLocalAddress(); } - @SuppressWarnings("removal") + @SuppressWarnings() SecurityManager s = System.getSecurityManager(); if (s != null) { s.checkConnect(in.getHostAddress(), -1); } } catch (Exception e) { - in = InetAddress.anyLocalAddress(); // "0.0.0.0" + in = InetAddress.anyLocalAddress(); // } return in; } @@ -8811,16 +8018,16 @@ final class NetMulticastSocket extends MulticastSocket { @Override public synchronized void setSoTimeout(int timeout) throws SocketException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); if (timeout < 0) - throw new IllegalArgumentException("timeout < 0"); + throw new IllegalArgumentException(); getImpl().setOption(SocketOptions.SO_TIMEOUT, timeout); } @Override public synchronized int getSoTimeout() throws SocketException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); if (getImpl() == null) return 0; Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT); @@ -8835,17 +8042,17 @@ final class NetMulticastSocket extends MulticastSocket { @Override public synchronized void setSendBufferSize(int size) throws SocketException { if (!(size > 0)) { - throw new IllegalArgumentException("negative send size"); + throw new IllegalArgumentException(); } if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); getImpl().setOption(SocketOptions.SO_SNDBUF, size); } @Override public synchronized int getSendBufferSize() throws SocketException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); int result = 0; Object o = getImpl().getOption(SocketOptions.SO_SNDBUF); if (o instanceof Integer) { @@ -8857,17 +8064,17 @@ final class NetMulticastSocket extends MulticastSocket { @Override public synchronized void setReceiveBufferSize(int size) throws SocketException { if (size <= 0) { - throw new IllegalArgumentException("invalid receive size"); + throw new IllegalArgumentException(); } if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); getImpl().setOption(SocketOptions.SO_RCVBUF, size); } @Override public synchronized int getReceiveBufferSize() throws SocketException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); int result = 0; Object o = getImpl().getOption(SocketOptions.SO_RCVBUF); if (o instanceof Integer) { @@ -8879,14 +8086,14 @@ final class NetMulticastSocket extends MulticastSocket { @Override public synchronized void setReuseAddress(boolean on) throws SocketException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on)); } @Override public synchronized boolean getReuseAddress() throws SocketException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); Object o = getImpl().getOption(SocketOptions.SO_REUSEADDR); return ((Boolean) o).booleanValue(); } @@ -8894,24 +8101,24 @@ final class NetMulticastSocket extends MulticastSocket { @Override public synchronized void setBroadcast(boolean on) throws SocketException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(on)); } @Override public synchronized boolean getBroadcast() throws SocketException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); return ((Boolean) (getImpl().getOption(SocketOptions.SO_BROADCAST))).booleanValue(); } @Override public synchronized void setTrafficClass(int tc) throws SocketException { if (tc < 0 || tc > 255) - throw new IllegalArgumentException("tc is not in range 0 -- 255"); + throw new IllegalArgumentException(); if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); try { getImpl().setOption(SocketOptions.IP_TOS, tc); } catch (SocketException se) { @@ -8925,7 +8132,7 @@ final class NetMulticastSocket extends MulticastSocket { @Override public synchronized int getTrafficClass() throws SocketException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); return ((Integer) (getImpl().getOption(SocketOptions.IP_TOS))).intValue(); } @@ -8952,7 +8159,7 @@ final class NetMulticastSocket extends MulticastSocket { { Objects.requireNonNull(name); if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); getImpl().setOption(name, value); return this; } @@ -8961,7 +8168,7 @@ final class NetMulticastSocket extends MulticastSocket { public T getOption(SocketOption name) throws IOException { Objects.requireNonNull(name); if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); return getImpl().getOption(name); } @@ -9009,7 +8216,7 @@ final class NetMulticastSocket extends MulticastSocket { private final Object infLock = new Object(); /** - * The "last" interface set by setInterface on this MulticastSocket + * The interface set by setInterface on this MulticastSocket */ private InetAddress infAddress = null; @@ -9017,17 +8224,17 @@ final class NetMulticastSocket extends MulticastSocket { @Override public void setTTL(byte ttl) throws IOException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); getImpl().setTTL(ttl); } @Override public void setTimeToLive(int ttl) throws IOException { if (ttl < 0 || ttl > 255) { - throw new IllegalArgumentException("ttl out of range"); + throw new IllegalArgumentException(); } if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); getImpl().setTimeToLive(ttl); } @@ -9035,14 +8242,14 @@ final class NetMulticastSocket extends MulticastSocket { @Override public byte getTTL() throws IOException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); return getImpl().getTTL(); } @Override public int getTimeToLive() throws IOException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); return getImpl().getTimeToLive(); } @@ -9050,18 +8257,18 @@ final class NetMulticastSocket extends MulticastSocket { @Deprecated public void joinGroup(InetAddress mcastaddr) throws IOException { if (isClosed()) { - throw new SocketException("Socket is closed"); + throw new SocketException(); } - checkAddress(mcastaddr, "joinGroup"); - @SuppressWarnings("removal") + checkAddress(mcastaddr, ); + @SuppressWarnings() SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkMulticast(mcastaddr); } if (!mcastaddr.isMulticastAddress()) { - throw new SocketException("Not a multicast address"); + throw new SocketException(); } /** @@ -9081,18 +8288,18 @@ final class NetMulticastSocket extends MulticastSocket { @Deprecated public void leaveGroup(InetAddress mcastaddr) throws IOException { if (isClosed()) { - throw new SocketException("Socket is closed"); + throw new SocketException(); } - checkAddress(mcastaddr, "leaveGroup"); - @SuppressWarnings("removal") + checkAddress(mcastaddr, ); + @SuppressWarnings() SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkMulticast(mcastaddr); } if (!mcastaddr.isMulticastAddress()) { - throw new SocketException("Not a multicast address"); + throw new SocketException(); } getImpl().leave(mcastaddr); @@ -9102,20 +8309,20 @@ final class NetMulticastSocket extends MulticastSocket { public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf) throws IOException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); if (!(mcastaddr instanceof InetSocketAddress addr)) - throw new IllegalArgumentException("Unsupported address type"); + throw new IllegalArgumentException(); - checkAddress(addr.getAddress(), "joinGroup"); - @SuppressWarnings("removal") + checkAddress(addr.getAddress(), ); + @SuppressWarnings() SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkMulticast(addr.getAddress()); } if (!addr.getAddress().isMulticastAddress()) { - throw new SocketException("Not a multicast address"); + throw new SocketException(); } getImpl().joinGroup(mcastaddr, netIf); @@ -9125,20 +8332,20 @@ final class NetMulticastSocket extends MulticastSocket { public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) throws IOException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); if (!(mcastaddr instanceof InetSocketAddress addr)) - throw new IllegalArgumentException("Unsupported address type"); + throw new IllegalArgumentException(); - checkAddress(addr.getAddress(), "leaveGroup"); - @SuppressWarnings("removal") + checkAddress(addr.getAddress(), ); + @SuppressWarnings() SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkMulticast(addr.getAddress()); } if (!addr.getAddress().isMulticastAddress()) { - throw new SocketException("Not a multicast address"); + throw new SocketException(); } getImpl().leaveGroup(mcastaddr, netIf); @@ -9148,9 +8355,9 @@ final class NetMulticastSocket extends MulticastSocket { @Deprecated public void setInterface(InetAddress inf) throws SocketException { if (isClosed()) { - throw new SocketException("Socket is closed"); + throw new SocketException(); } - checkAddress(inf, "setInterface"); + checkAddress(inf, ); synchronized (infLock) { getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf); infAddress = inf; @@ -9162,7 +8369,7 @@ final class NetMulticastSocket extends MulticastSocket { @Deprecated public InetAddress getInterface() throws SocketException { if (isClosed()) { - throw new SocketException("Socket is closed"); + throw new SocketException(); } synchronized (infLock) { InetAddress ia = @@ -9246,20 +8453,20 @@ final class NetMulticastSocket extends MulticastSocket { return ((Boolean)getImpl().getOption(SocketOptions.IP_MULTICAST_LOOP)).booleanValue(); } - @SuppressWarnings("removal") + @SuppressWarnings() @Deprecated @Override public void send(DatagramPacket p, byte ttl) throws IOException { if (isClosed()) - throw new SocketException("Socket is closed"); + throw new SocketException(); synchronized(ttlLock) { synchronized(p) { InetAddress packetAddress = p.getAddress(); - checkAddress(packetAddress, "send"); + checkAddress(packetAddress, ); if (connectState == NetMulticastSocket.ST_NOT_CONNECTED) { if (packetAddress == null) { - throw new IllegalArgumentException("Address not set"); + throw new IllegalArgumentException(); } // Security manager makes sure that the multicast address // is allowed one and that the ttl used is less @@ -9280,8 +8487,8 @@ final class NetMulticastSocket extends MulticastSocket { p.setPort(connectedPort); } else if ((!packetAddress.equals(connectedAddress)) || p.getPort() != connectedPort) { - throw new IllegalArgumentException("connected address and packet address" + - " differ"); + throw new IllegalArgumentException( + + ); } } byte dttl = getTTL(); @@ -9291,7 +8498,7 @@ final class NetMulticastSocket extends MulticastSocket { getImpl().setTTL(ttl); } if (p.getPort() == 0) { - throw new SocketException("Can't send to port 0"); + throw new SocketException(); } // call the datagram method to send getImpl().send(p); @@ -9313,7 +8520,7 @@ final class NetMulticastSocket extends MulticastSocket { * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided + * particular file as subject to the exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT @@ -9349,7 +8556,7 @@ import java.util.Objects; * The piped input stream contains a buffer, * decoupling read operations from write operations, * within limits. - * A pipe is said to be broken if a + * A pipe is said to be broken if a * thread that was providing data bytes to the connected * piped output stream is no longer alive. * @@ -9466,7 +8673,7 @@ public class PipedInputStream extends InputStream { private void initPipe(int pipeSize) { if (pipeSize <= 0) { - throw new IllegalArgumentException("Pipe Size <= 0"); + throw new IllegalArgumentException(); } buffer = new byte[pipeSize]; } @@ -9506,7 +8713,7 @@ public class PipedInputStream extends InputStream { * Receives a byte of data. This method will block if no input is * available. * @param b the byte being received - * @throws IOException If the pipe is {@code broken}, + * @throws IOException If the pipe is {@code broken}, * {@link #connect(java.io.PipedOutputStream) unconnected}, * closed, or if an I/O error occurs. * @since 1.1 @@ -9532,7 +8739,7 @@ public class PipedInputStream extends InputStream { * @param b the buffer into which the data is received * @param off the start offset of the data * @param len the maximum number of bytes received - * @throws IOException If the pipe is broken, + * @throws IOException If the pipe is broken, * {@link #connect(java.io.PipedOutputStream) unconnected}, * closed, or if an I/O error occurs. */ @@ -9569,11 +8776,11 @@ public class PipedInputStream extends InputStream { private void checkStateForReceive() throws IOException { if (!connected) { - throw new IOException("Pipe not connected"); + throw new IOException(); } else if (closedByWriter || closedByReader) { - throw new IOException("Pipe closed"); + throw new IOException(); } else if (readSide != null && !readSide.isAlive()) { - throw new IOException("Read end dead"); + throw new IOException(); } } @@ -9610,18 +8817,18 @@ public class PipedInputStream extends InputStream { * @return {@inheritDoc} * @throws IOException if the pipe is * {@link #connect(java.io.PipedOutputStream) unconnected}, - * {@code broken}, closed, + * {@code broken}, closed, * or if an I/O error occurs. */ @Override public synchronized int read() throws IOException { if (!connected) { - throw new IOException("Pipe not connected"); + throw new IOException(); } else if (closedByReader) { - throw new IOException("Pipe closed"); + throw new IOException(); } else if (writeSide != null && !writeSide.isAlive() && !closedByWriter && (in < 0)) { - throw new IOException("Write end dead"); + throw new IOException(); } readSide = Thread.currentThread(); @@ -9632,7 +8839,7 @@ public class PipedInputStream extends InputStream { return -1; } if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) { - throw new IOException("Pipe broken"); + throw new IOException(); } /* might be a writer waiting */ notifyAll(); @@ -9670,7 +8877,7 @@ public class PipedInputStream extends InputStream { * @return {@inheritDoc} * @throws NullPointerException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} - * @throws IOException if the pipe is {@code broken}, + * @throws IOException if the pipe is {@code broken}, * {@link #connect(java.io.PipedOutputStream) unconnected}, * closed, or if an I/O error occurs. */ @@ -9729,7 +8936,7 @@ public class PipedInputStream extends InputStream { * without blocking, or {@code 0} if this input stream has been * closed by invoking its {@link #close()} method, or if the pipe * is {@link #connect(java.io.PipedOutputStream) unconnected}, or - * {@code broken}. + * {@code broken}. * * @throws IOException {@inheritDoc} * @since 1.0.2