h&GxF 4      !"#$%&'()*+,-./0123(c) 2022 Andrew Lelechenko (c) 2023 Pierre Le MarreBSD3/Andrew Lelechenko  Safe-Inferred $(144text-builder-linearReplicate an ASCII characterWarning:; it is the responsibility of the caller to ensure that the 5 is a valid ASCII character.6text-builder-linear)Duplicate a portion of an array in-place.Example of use:  -- Write count times the char c let cLen = utf8Length c; totalLen = cLen * count in unsafeWrite dst dstOff ch *> 6 dst dstOff totalLen cLen 4text-builder-linear Mutable arraytext-builder-linearOffsettext-builder-linearCounttext-builder-linearASCII character6text-builder-linear Mutable arraytext-builder-linear!Start of the portion to duplicatetext-builder-linearTotal length of the duplicatetext-builder-linear"Length of the portion to duplicate78946(c) 2022 Andrew Lelechenko (c) 2023 Pierre Le MarreBSD3/Andrew Lelechenko  Safe-Inferred$(14"etext-builder-linear Internally  is a mutable buffer. If a client gets hold of a variable of type , they'd be able to pass a mutable buffer to concurrent threads. That's why API below is carefully designed to prevent such possibility: clients always work with linear functions  E # instead and run them on an empty  to extract results. In terms of  /https://hackage.haskell.org/package/linear-base linear-base  is  https://hackage.haskell.org/package/linear-base/docs/Prelude-Linear.html#t:Consumable Consumable (see ) and  https://hackage.haskell.org/package/linear-base/docs/Prelude-Linear.html#t:DupableDupable (see  ), but not  https://hackage.haskell.org/package/linear-base/docs/Prelude-Linear.html#t:MovableMovable.&:set -XOverloadedStrings -XLinearTypes&import Data.Text.Builder.Linear.Buffer7runBuffer (\b -> '!' .<| "foo" <| (b |> "bar" |>. '.')) "!foobar."6Remember: this is a strict builder, so on contrary to Data.Text.Lazy.Builder for optimal performance you should use strict left folds instead of lazy right ones. is an unlifted datatype, so you can put it into an unboxed tuple (# ..., ... #), but not into  (..., ...).:text-builder-linearUnwrap , no-op. Most likely, this is not the function you're looking for and you need  instead.text-builder-linear"Run a linear function on an empty , producing a strict ;.Be careful to write runBuffer (\b -> ...) instead of runBuffer $ \b -> ..., because current implementation of linear types lacks special support for <. Another option is to enable {-# LANGUAGE BlockArguments #-} and write runBuffer \b -> ...". Alternatively, you can import  https://hackage.haskell.org/package/linear-base/docs/Prelude-Linear.html#v:-36-($) from  /https://hackage.haskell.org/package/linear-base linear-base.0 is similar in spirit to mutable arrays API in  https://hackage.haskell.org/package/linear-base/docs/Data-Array-Mutable-Linear.htmlData.Array.Mutable.Linear", which provides functions like  https://hackage.haskell.org/package/linear-base/docs/Data-Array-Mutable-Linear.html#v:fromListfromList D [a] C (Vector a E  https://hackage.haskell.org/package/linear-base-0.3.0/docs/Prelude-Linear.html#t:UrUr b) E  https://hackage.haskell.org/package/linear-base-0.3.0/docs/Prelude-Linear.html#t:UrUr b/. Here the initial buffer is always empty and b is ;. Since ; is  https://hackage.haskell.org/package/linear-base/docs/Prelude-Linear.html#t:MovableMovable, ; and  https://hackage.haskell.org/package/linear-base-0.3.0/docs/Prelude-Linear.html#t:UrUr ; are equivalent.text-builder-linearSame as ', but returning a UTF-8 encoded strict =.text-builder-linearCreate an empty . The first , is the input and the second is a new empty .7This function is needed in some situations, e.g. with . The following example creates a utility function that justify a text and then append it to a buffer.6:set -XOverloadedStrings -XLinearTypes -XUnboxedTuples&import Data.Text.Builder.Linear.Bufferimport Data.Text (Text):{.appendJustified :: Buffer %1 -> Text -> Buffer.appendJustified b t = case newEmptyBuffer b of -- Note that we need to create a new buffer from the text, in order7 -- to justify only the text and not the input buffer.; (# b', empty #) -> b' >< justifyRight 12 ' ' (empty |> t):}runBuffer (\b -> (b |> "Test:") `appendJustified` "foo" `appendJustified` "bar")"Test: foo bar"Note: a previous buffer is necessary in order to create an empty buffer with the same characteristics.text-builder-linearDuplicate builder. Feel free to process results in parallel threads. Similar to  https://hackage.haskell.org/package/linear-base/docs/Prelude-Linear.html#t:DupableDupable from  /https://hackage.haskell.org/package/linear-base linear-base.&It is a bit tricky to use because of  https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/linear_types.html#limitationscurrent limitations" of linear types with regards to let and where. E. g., one cannot write let (# b1, b2 #) = dupBuffer b in ("foo" <| b1) >< (b2 |> "bar")Instead write:6:set -XOverloadedStrings -XLinearTypes -XUnboxedTuples&import Data.Text.Builder.Linear.BufferrunBuffer (\b -> case dupBuffer b of (# b1, b2 #) -> ("foo" <| b1) >< (b2 |> "bar"))"foobar"Note the unboxed tuple: 4 is an unlifted datatype, so it cannot be put into  (..., ...).text-builder-linear&Consume buffer linearly, similar to  https://hackage.haskell.org/package/linear-base/docs/Prelude-Linear.html#t:Consumable Consumable from  /https://hackage.haskell.org/package/linear-base linear-base.text-builder-linear3Erase buffer's content, replacing it with an empty ;.text-builder-linearReturn buffer's size in bytes (not in >s). This could be useful to implement a lazy builder atop of a strict one.text-builder-linearReturn buffer's length in >5s (not in bytes). This could be useful to implement  dropEndBuffer and  takeEndBuffer, e. g., import Data.Unrestricted.Linear dropEndBuffer :: Word -> Buffer %1 -> Buffer dropEndBuffer n buf = case lengthOfBuffer buf of (# buf', len #) -> case move len of Ur len' -> takeBuffer (len' - n) buf' text-builder-linearSlice  by dropping given number of >s. text-builder-linearSlice  by taking given number of >s. text-builder-linear6Low-level routine to append data of unknown size to a . text-builder-linear4Low-level routine to append data of known size to a . text-builder-linear7Low-level routine to prepend data of unknown size to a .text-builder-linear4Low-level routine to append data of known size to a .text-builder-linearConcatenate two %s, potentially mutating both of them.You likely need to use % to get hold on two builders at once:6:set -XOverloadedStrings -XLinearTypes -XUnboxedTuples&import Data.Text.Builder.Linear.BufferrunBuffer (\b -> case dupBuffer b of (# b1, b2 #) -> ("foo" <| b1) >< (b2 |> "bar"))"foobar" text-builder-linear9Upper bound for the number of bytes, written by an actiontext-builder-linearAction, which writes bytes starting from the given offset and returns an actual number of bytes written. text-builder-linear+Exact number of bytes, written by an actiontext-builder-linearAction, which writes bytes starting from the given offset text-builder-linear9Upper bound for the number of bytes, written by an actiontext-builder-linearAction, which writes bytes  finishing before the given offset and returns an actual number of bytes written.text-builder-linearAction, which writes bytes starting from the given offset and returns an actual number of bytes written.text-builder-linear+Exact number of bytes, written by an actiontext-builder-linearAction, which writes bytes starting from the given offset   6(c) 2022 Andrew LelechenkoBSD3/Andrew Lelechenko  Safe-Inferred$(14-+text-builder-linearAppend > to a  by mutating it.:set -XLinearTypes#runBuffer (\b -> b |>. 'q' |>. 'w')"qw"Warning: In contrast to , it is the responsibility of the caller to sanitize surrogate code points with  .text-builder-linearPrepend > to a  by mutating it.:set -XLinearTypes#runBuffer (\b -> 'q' .<| 'w' .<| b)"qw"Warning: In contrast to , it is the responsibility of the caller to sanitize surrogate code points with  .?text-builder-linear Similar to @&, but writes _before_ a given offset.text-builder-linearPrepend a given count of a > to a .:set -XLinearTypes0runBuffer (\b -> prependChars 3 'x' (b |>. 'A'))"xxxA"text-builder-linearApppend a given count of a > to a .:set -XLinearTypes/runBuffer (\b -> appendChars 3 'x' (b |>. 'A'))"Axxx"text-builder-linearPad a builder from the left< side to the specified length with the specified character.:set -XLinearTypes;runBuffer (\b -> justifyRight 10 'x' (appendChars 3 'A' b)) "xxxxxxxAAA":runBuffer (\b -> justifyRight 5 'x' (appendChars 6 'A' b))"AAAAAA" Note that  is needed in some situations. The following example creates a utility function that justify a text and then append it to a buffer.6:set -XOverloadedStrings -XLinearTypes -XUnboxedTuples&import Data.Text.Builder.Linear.Bufferimport Data.Text (Text):{.appendJustified :: Buffer %1 -> Text -> Buffer.appendJustified b t = case newEmptyBuffer b of -- Note that we need to create a new buffer from the text, in order7 -- to justify only the text and not the input buffer.; (# b', empty #) -> b' >< justifyRight 12 ' ' (empty |> t):}runBuffer (\b -> (b |> "Test:") `appendJustified` "foo" `appendJustified` "bar")"Test: foo bar"text-builder-linearPad a builder from the right< side to the specified length with the specified character.:set -XLinearTypes:runBuffer (\b -> justifyLeft 10 'x' (appendChars 3 'A' b)) "AAAxxxxxxx"9runBuffer (\b -> justifyLeft 5 'x' (appendChars 6 'A' b))"AAAAAA" Note that # is needed in some situations. See  for an example.text-builder-linearCenter a builder to the specified length with the specified character.:set -XLinearTypes5runBuffer (\b -> center 10 'x' (appendChars 3 'A' b)) "xxxxAAAxxx"4runBuffer (\b -> center 5 'x' (appendChars 6 'A' b))"AAAAAA" Note that # is needed in some situations. See  for an example.66 (c) 2022 Andrew LelechenkoBSD3/Andrew Lelechenko  Safe-Inferred $(14.text-builder-linearAppend decimal number.text-builder-linearPrepend decimal number.Atext-builder-linear4ceiling (fbs a * logBase 10 2) < ceiling (fbs a * 5  16) < 1 + floor (fbs a * 5  16)66 (c) 2022 Andrew LelechenkoBSD3/Andrew Lelechenko  Safe-Inferred$(14/xtext-builder-linearAppend double.text-builder-linearPrepend double.66 (c) 2022 Andrew LelechenkoBSD3/Andrew Lelechenko  Safe-Inferred$(144text-builder-linear=Append the lower-case hexadecimal represensation of a number.Negative numbers are interpreted as their corresponding unsigned number, e.g.&:set -XOverloadedStrings -XLinearTypesimport Data.Int (Int8, Int16),runBuffer (\b -> b |>& (-1 :: Int8)) == "ff"True/runBuffer (\b -> b |>& (-1 :: Int16)) == "ffff"Truetext-builder-linear>Prepend the lower-case hexadecimal representation of a number.Negative numbers are interpreted as their corresponding unsigned number, e.g.&:set -XOverloadedStrings -XLinearTypesimport Data.Int (Int8, Int16),runBuffer (\b -> (-1 :: Int8) &<| b) == "ff"True/runBuffer (\b -> (-1 :: Int16) &<| b) == "ffff"TrueBtext-builder-linearCompute the number of nibbles that an integral type can hold, rounded up.Ctext-builder-linear The usual D performs sign extension on signed number types, filling the top bits with 1 if the argument is negative. We don't want this behaviour here.It would suffice to clean the sign bit only once instead of doing it on every iteration of unsafe{Ap,Pre}pernHex.go, but the performance impact is likely negligible.Etext-builder-linear;This assumes n /= 0. Round the number of nibbles up, as in B.66(c) 2022 Andrew Lelechenko (c) 2023 Pierre Le MarreBSD3/Andrew Lelechenko  Safe-Inferred$(14<text-builder-linearAppend ; suffix to a  by mutating it. If a suffix is statically known, consider using  for optimal performance.&:set -XOverloadedStrings -XLinearTypes%runBuffer (\b -> b |> "foo" |> "bar")"foobar"text-builder-linearPrepend ; prefix to a  by mutating it. If a prefix is statically known, consider using   for optimal performance.&:set -XOverloadedStrings -XLinearTypes%runBuffer (\b -> "foo" <| "bar" <| b)"foobar"text-builder-linear,Append a null-terminated UTF-8 string to a  by mutating it. E. g.,2:set -XOverloadedStrings -XLinearTypes -XMagicHash)runBuffer (\b -> b |># "foo"# |># "bar"#)"foobar"/The literal string must not contain zero bytes \0> and must be a valid UTF-8, these conditions are not checked. text-builder-linear-Prepend a null-terminated UTF-8 string to a  by mutating it. E. g.,2:set -XOverloadedStrings -XLinearTypes -XMagicHash)runBuffer (\b -> "foo"# #<| "bar"# #<| b)"foobar"/The literal string must not contain zero bytes \0> and must be a valid UTF-8, these conditions are not checked.Note: When the syntactic extensions  UnboxedTuples or  UnboxedSums are enabled, extra spaces are required when using parentheses: i.e. use (   ) instead of ( ). See the GHC User Guide chapter @[Unboxed types and primitive operations](https:/downloads.haskell.orgghclatestdocs users_guide?exts/primitives.html#unboxed-tuples)@ for further information.!text-builder-linear Alias for  ."text-builder-linearAppend given number of spaces.#text-builder-linearPrepend given number of spaces.$text-builder-linearThis is just a normal 4, but with a linear arrow and unlifted accumulator. !"#$$"# !666 6!6"6#6(c) 2022 Andrew LelechenkoBSD3/Andrew Lelechenko  Safe-Inferred$(14E %text-builder-linearThin wrapper over  with a handy F instance.$:set -XOverloadedStrings -XMagicHash1fromText "foo" <> fromChar '_' <> fromAddr "bar"# "foo_bar"6Remember: this is a strict builder, so on contrary to Data.Text.Lazy.Builder for optimal performance you should use strict left folds instead of lazy right ones.7Note that (similar to other builders) concatenation of %s allocates thunks. This is to a certain extent mitigated by aggressive inlining, but it is faster to use  directly.(text-builder-linearRun % computation on an empty , returning strict ;.$:set -XOverloadedStrings -XMagicHash>runBuilder (fromText "foo" <> fromChar '_' <> fromAddr "bar"#) "foo_bar"This function has a polymorphic arrow and thus can be used both in usual and linear contexts.)text-builder-linearSame as (', but returning a UTF-8 encoded strict =.*text-builder-linearCreate %, containing a given ;.:set -XOverloadedStrings fromText "foo" <> fromText "bar""foobar"+text-builder-linearCreate %, containing a given >.fromChar 'x' <> fromChar 'y'"xy"In contrast to , it's a responsibility of the caller to sanitize surrogate code points with  .,text-builder-linearCreate %:, containing a null-terminated UTF-8 string, specified by G.:set -XMagicHash"fromAddr "foo"# <> fromAddr "bar"#"foobar"/The literal string must not contain zero bytes \0> and must be a valid UTF-8, these conditions are not checked.-text-builder-linearCreate %7, containing decimal representation of a given integer.$fromChar 'x' <> fromDec (123 :: Int)"x123".text-builder-linearCreate %;, containing hexadecimal representation of a given integer.:set -XMagicHash+fromAddr "0x"# <> fromHex (0x123def :: Int) "0x123def"/text-builder-linearCreate %/, containing decimal representation of a given H.:set -XMagicHash fromAddr "pi="# <> fromDouble pi"pi=3.141592653589793" %&'()*+,-./ %&'()*+,-./ !"#$% & ' ( ) * +,-./01234456789:;<=>?@ABCDEFGHIJK LMNOPQRCDSTKUV W X YMZ[ \MN]C^_CD`0text-builder-linear-0.1.2-EW6Ocw26eZx6ZUhzEPOZbIData.Text.Builder.Linear.CoreData.Text.Builder.Linear.BufferData.Text.Builder.LinearData.Text.Builder.Linear.Array justifyRightData.Text.Builder.Linear.CharData.Text.Lazy.Builder singletonData.Text.InternalsafeData.Text.Builder.Linear.DecData.Text.Builder.Linear.DoubleData.Text.Builder.Linear.Hex Data.Listfoldl'Buffer runBuffer runBufferBSnewEmptyBuffer dupBuffer consumeBuffer eraseBufferbyteSizeOfBufferlengthOfBuffer dropBuffer takeBuffer appendBounded appendExactprependBounded prependExact><|>..<| prependChars appendChars justifyLeftcenter|>$$<||>%%<||>&&<||><||>##<|<|#|>……<|foldlIntoBufferBuilder unBuilder runBuilder runBuilderBSfromTextfromCharfromAddrfromDecfromHex fromDouble$fIsStringBuilder$fMonoidBuilder$fSemigroupBuilder $fShowBuilderunsafeReplicateghc-prim GHC.TypesInt unsafeTile unsafeThawsizeofByteArrayisPinnedunBuffertext-2.1-9HM8jbghPTNGoq78q5e19bTextbaseGHC.Base$bytestring-0.11.3.1Data.ByteString.Internal ByteStringCharunsafePrependCharMData.Text.Internal.Unsafe.Char unsafeWrite maxDecLen maxHexLen dropNibbleGHC.BitsshiftR lengthAsHex SemigroupGHC.PrimAddr#Double