-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Strict Text and ByteString builder, which hides mutable buffer behind
--   linear types and takes amortized linear time.
@package text-builder-linear
@version 0.1.3


-- | Low-level routines for <a>Buffer</a> manipulations.
module Data.Text.Builder.Linear.Core

-- | Internally <a>Buffer</a> is a mutable buffer. If a client gets hold of
--   a variable of type <a>Buffer</a>, 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 <a>Buffer</a> ⊸ <a>Buffer</a> instead and run them on an
--   empty <a>Buffer</a> to extract results.
--   
--   In terms of <a><tt>linear-base</tt></a> <a>Buffer</a> is
--   <a><tt>Consumable</tt></a> (see <a>consumeBuffer</a>) and
--   <a><tt>Dupable</tt></a> (see <a>dupBuffer</a>), but not
--   <a><tt>Movable</tt></a>.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes
--   
--   &gt;&gt;&gt; import Data.Text.Builder.Linear.Buffer
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; '!' .&lt;| "foo" &lt;| (b |&gt; "bar" |&gt;. '.'))
--   "!foobar."
--   </pre>
--   
--   Remember: this is a strict builder, so on contrary to
--   <a>Data.Text.Lazy.Builder</a> for optimal performance you should use
--   strict left folds instead of lazy right ones.
--   
--   <a>Buffer</a> is an unlifted datatype, so you can put it into an
--   unboxed tuple <tt>(# ..., ... #)</tt>, but not into <tt>(...,
--   ...)</tt>.
data Buffer :: UnliftedType

-- | Run a linear function on an empty <a>Buffer</a>, producing a strict
--   <a>Text</a>.
--   
--   Be careful to write <tt>runBuffer (\b -&gt; ...)</tt> instead of
--   <tt>runBuffer $ \b -&gt; ...</tt>, because current implementation of
--   linear types lacks special support for <a>($)</a>. Another option is
--   to enable <tt>{-# LANGUAGE BlockArguments #-}</tt> and write
--   <tt>runBuffer \b -&gt; ...</tt>. Alternatively, you can import
--   <a><tt>($)</tt></a> from <a><tt>linear-base</tt></a>.
--   
--   <a>runBuffer</a> is similar in spirit to mutable arrays API in
--   <a><tt>Data.Array.Mutable.Linear</tt></a>, which provides functions
--   like <a><tt>fromList</tt></a> ∷ [<tt>a</tt>] → (<tt>Vector</tt>
--   <tt>a</tt> ⊸ <a><tt>Ur</tt></a> b) ⊸ <a><tt>Ur</tt></a> <tt>b</tt>.
--   Here the initial buffer is always empty and <tt>b</tt> is <a>Text</a>.
--   Since <a>Text</a> is <a><tt>Movable</tt></a>, <a>Text</a> and
--   <a><tt>Ur</tt></a> <a>Text</a> are equivalent.
runBuffer :: (Buffer %1 -> Buffer) %1 -> Text

-- | Same as <a>runBuffer</a>, but returning a UTF-8 encoded strict
--   <a>ByteString</a>.
runBufferBS :: (Buffer %1 -> Buffer) %1 -> ByteString

-- | Duplicate builder. Feel free to process results in parallel threads.
--   Similar to <a><tt>Dupable</tt></a> from <a><tt>linear-base</tt></a>.
--   
--   It is a bit tricky to use because of <a>current limitations</a> of
--   linear types with regards to <tt>let</tt> and <tt>where</tt>. E. g.,
--   one cannot write
--   
--   <pre>
--   let (# b1, b2 #) = dupBuffer b in ("foo" &lt;| b1) &gt;&lt; (b2 |&gt; "bar")
--   </pre>
--   
--   Instead write:
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes -XUnboxedTuples
--   
--   &gt;&gt;&gt; import Data.Text.Builder.Linear.Buffer
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; case dupBuffer b of (# b1, b2 #) -&gt; ("foo" &lt;| b1) &gt;&lt; (b2 |&gt; "bar"))
--   "foobar"
--   </pre>
--   
--   Note the unboxed tuple: <a>Buffer</a> is an unlifted datatype, so it
--   cannot be put into <tt>(..., ...)</tt>.
dupBuffer :: Buffer %1 -> (# Buffer, Buffer #)

-- | Consume buffer linearly, similar to <a><tt>Consumable</tt></a> from
--   <a><tt>linear-base</tt></a>.
consumeBuffer :: Buffer %1 -> ()

-- | Erase buffer's content, replacing it with an empty <a>Text</a>.
eraseBuffer :: Buffer %1 -> Buffer

-- | Return buffer's size in <b>bytes</b> (not in <a>Char</a>s). This could
--   be useful to implement a lazy builder atop of a strict one.
byteSizeOfBuffer :: Buffer %1 -> (# Buffer, Word #)

-- | Return buffer's length in <a>Char</a>s (not in bytes). This could be
--   useful to implement <tt>dropEndBuffer</tt> and <tt>takeEndBuffer</tt>,
--   e. g.,
--   
--   <pre>
--   import Data.Unrestricted.Linear
--   
--   dropEndBuffer :: Word -&gt; Buffer %1 -&gt; Buffer
--   dropEndBuffer n buf = case lengthOfBuffer buf of
--     (# buf', len #) -&gt; case move len of
--       Ur len' -&gt; takeBuffer (len' - n) buf'
--   </pre>
lengthOfBuffer :: Buffer %1 -> (# Buffer, Word #)

-- | Slice <a>Buffer</a> by dropping given number of <a>Char</a>s.
dropBuffer :: Word -> Buffer %1 -> Buffer

-- | Slice <a>Buffer</a> by taking given number of <a>Char</a>s.
takeBuffer :: Word -> Buffer %1 -> Buffer

-- | Create an empty <a>Buffer</a>.
--   
--   The first <a>Buffer</a> is the input and the second is a new empty
--   <a>Buffer</a>.
--   
--   This function is needed in some situations, e.g. with
--   <a>justifyRight</a>. The following example creates a utility function
--   that justify a text and then append it to a buffer.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes -XUnboxedTuples
--   
--   &gt;&gt;&gt; import Data.Text.Builder.Linear.Buffer
--   
--   &gt;&gt;&gt; import Data.Text (Text)
--   
--   &gt;&gt;&gt; :{
--   appendJustified :: Buffer %1 -&gt; Text -&gt; Buffer
--   appendJustified b t = case newEmptyBuffer b of
--     -- Note that we need to create a new buffer from the text, in order
--     -- to justify only the text and not the input buffer.
--     (# b', empty #) -&gt; b' &gt;&lt; justifyRight 12 ' ' (empty |&gt; t)
--   :}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; runBuffer (\b -&gt; (b |&gt; "Test:") `appendJustified` "AAA" `appendJustified` "BBBBBBB")
--   "Test:         AAA     BBBBBBB"
--   </pre>
--   
--   Note: a previous buffer is necessary in order to create an empty
--   buffer with the same characteristics.
newEmptyBuffer :: Buffer %1 -> (# Buffer, Buffer #)

-- | Low-level routine to append data of unknown size to a <a>Buffer</a>.
appendBounded :: Int -> (forall s. () => MArray s -> Int -> ST s Int) -> Buffer %1 -> Buffer

-- | Low-level routine to append data of known size to a <a>Buffer</a>.
appendExact :: Int -> (forall s. () => MArray s -> Int -> ST s ()) -> Buffer %1 -> Buffer

-- | Low-level routine to prepend data of unknown size to a <a>Buffer</a>.
prependBounded :: Int -> (forall s. () => MArray s -> Int -> ST s Int) -> (forall s. () => MArray s -> Int -> ST s Int) -> Buffer %1 -> Buffer

-- | Low-level routine to append data of known size to a <a>Buffer</a>.
prependExact :: Int -> (forall s. () => MArray s -> Int -> ST s ()) -> Buffer %1 -> Buffer

-- | Concatenate two <a>Buffer</a>s, potentially mutating both of them.
--   
--   You likely need to use <a>dupBuffer</a> to get hold on two builders at
--   once:
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes -XUnboxedTuples
--   
--   &gt;&gt;&gt; import Data.Text.Builder.Linear.Buffer
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; case dupBuffer b of (# b1, b2 #) -&gt; ("foo" &lt;| b1) &gt;&lt; (b2 |&gt; "bar"))
--   "foobar"
--   </pre>
(><) :: Buffer %1 -> Buffer %1 -> Buffer
infix 6 ><


-- | <a>Buffer</a> for strict <a>Text</a>, based on linear types.
module Data.Text.Builder.Linear.Buffer

-- | Internally <a>Buffer</a> is a mutable buffer. If a client gets hold of
--   a variable of type <a>Buffer</a>, 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 <a>Buffer</a> ⊸ <a>Buffer</a> instead and run them on an
--   empty <a>Buffer</a> to extract results.
--   
--   In terms of <a><tt>linear-base</tt></a> <a>Buffer</a> is
--   <a><tt>Consumable</tt></a> (see <a>consumeBuffer</a>) and
--   <a><tt>Dupable</tt></a> (see <a>dupBuffer</a>), but not
--   <a><tt>Movable</tt></a>.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes
--   
--   &gt;&gt;&gt; import Data.Text.Builder.Linear.Buffer
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; '!' .&lt;| "foo" &lt;| (b |&gt; "bar" |&gt;. '.'))
--   "!foobar."
--   </pre>
--   
--   Remember: this is a strict builder, so on contrary to
--   <a>Data.Text.Lazy.Builder</a> for optimal performance you should use
--   strict left folds instead of lazy right ones.
--   
--   <a>Buffer</a> is an unlifted datatype, so you can put it into an
--   unboxed tuple <tt>(# ..., ... #)</tt>, but not into <tt>(...,
--   ...)</tt>.
data Buffer :: UnliftedType

-- | Run a linear function on an empty <a>Buffer</a>, producing a strict
--   <a>Text</a>.
--   
--   Be careful to write <tt>runBuffer (\b -&gt; ...)</tt> instead of
--   <tt>runBuffer $ \b -&gt; ...</tt>, because current implementation of
--   linear types lacks special support for <a>($)</a>. Another option is
--   to enable <tt>{-# LANGUAGE BlockArguments #-}</tt> and write
--   <tt>runBuffer \b -&gt; ...</tt>. Alternatively, you can import
--   <a><tt>($)</tt></a> from <a><tt>linear-base</tt></a>.
--   
--   <a>runBuffer</a> is similar in spirit to mutable arrays API in
--   <a><tt>Data.Array.Mutable.Linear</tt></a>, which provides functions
--   like <a><tt>fromList</tt></a> ∷ [<tt>a</tt>] → (<tt>Vector</tt>
--   <tt>a</tt> ⊸ <a><tt>Ur</tt></a> b) ⊸ <a><tt>Ur</tt></a> <tt>b</tt>.
--   Here the initial buffer is always empty and <tt>b</tt> is <a>Text</a>.
--   Since <a>Text</a> is <a><tt>Movable</tt></a>, <a>Text</a> and
--   <a><tt>Ur</tt></a> <a>Text</a> are equivalent.
runBuffer :: (Buffer %1 -> Buffer) %1 -> Text

-- | Same as <a>runBuffer</a>, but returning a UTF-8 encoded strict
--   <a>ByteString</a>.
runBufferBS :: (Buffer %1 -> Buffer) %1 -> ByteString

-- | Duplicate builder. Feel free to process results in parallel threads.
--   Similar to <a><tt>Dupable</tt></a> from <a><tt>linear-base</tt></a>.
--   
--   It is a bit tricky to use because of <a>current limitations</a> of
--   linear types with regards to <tt>let</tt> and <tt>where</tt>. E. g.,
--   one cannot write
--   
--   <pre>
--   let (# b1, b2 #) = dupBuffer b in ("foo" &lt;| b1) &gt;&lt; (b2 |&gt; "bar")
--   </pre>
--   
--   Instead write:
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes -XUnboxedTuples
--   
--   &gt;&gt;&gt; import Data.Text.Builder.Linear.Buffer
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; case dupBuffer b of (# b1, b2 #) -&gt; ("foo" &lt;| b1) &gt;&lt; (b2 |&gt; "bar"))
--   "foobar"
--   </pre>
--   
--   Note the unboxed tuple: <a>Buffer</a> is an unlifted datatype, so it
--   cannot be put into <tt>(..., ...)</tt>.
dupBuffer :: Buffer %1 -> (# Buffer, Buffer #)

-- | Consume buffer linearly, similar to <a><tt>Consumable</tt></a> from
--   <a><tt>linear-base</tt></a>.
consumeBuffer :: Buffer %1 -> ()

-- | Erase buffer's content, replacing it with an empty <a>Text</a>.
eraseBuffer :: Buffer %1 -> Buffer

-- | This is just a normal <a>foldl'</a>, but with a linear arrow and
--   unlifted accumulator.
foldlIntoBuffer :: (Buffer %1 -> a -> Buffer) -> Buffer %1 -> [a] -> Buffer

-- | Create an empty <a>Buffer</a>.
--   
--   The first <a>Buffer</a> is the input and the second is a new empty
--   <a>Buffer</a>.
--   
--   This function is needed in some situations, e.g. with
--   <a>justifyRight</a>. The following example creates a utility function
--   that justify a text and then append it to a buffer.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes -XUnboxedTuples
--   
--   &gt;&gt;&gt; import Data.Text.Builder.Linear.Buffer
--   
--   &gt;&gt;&gt; import Data.Text (Text)
--   
--   &gt;&gt;&gt; :{
--   appendJustified :: Buffer %1 -&gt; Text -&gt; Buffer
--   appendJustified b t = case newEmptyBuffer b of
--     -- Note that we need to create a new buffer from the text, in order
--     -- to justify only the text and not the input buffer.
--     (# b', empty #) -&gt; b' &gt;&lt; justifyRight 12 ' ' (empty |&gt; t)
--   :}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; runBuffer (\b -&gt; (b |&gt; "Test:") `appendJustified` "AAA" `appendJustified` "BBBBBBB")
--   "Test:         AAA     BBBBBBB"
--   </pre>
--   
--   Note: a previous buffer is necessary in order to create an empty
--   buffer with the same characteristics.
newEmptyBuffer :: Buffer %1 -> (# Buffer, Buffer #)

-- | Concatenate two <a>Buffer</a>s, potentially mutating both of them.
--   
--   You likely need to use <a>dupBuffer</a> to get hold on two builders at
--   once:
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes -XUnboxedTuples
--   
--   &gt;&gt;&gt; import Data.Text.Builder.Linear.Buffer
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; case dupBuffer b of (# b1, b2 #) -&gt; ("foo" &lt;| b1) &gt;&lt; (b2 |&gt; "bar"))
--   "foobar"
--   </pre>
(><) :: Buffer %1 -> Buffer %1 -> Buffer
infix 6 ><

-- | Append <a>Char</a> to a <a>Buffer</a> by mutating it.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XLinearTypes
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; b |&gt;. 'q' |&gt;. 'w')
--   "qw"
--   </pre>
--   
--   <b>Warning:</b> In contrast to <a>singleton</a>, it is the
--   responsibility of the caller to sanitize surrogate code points with
--   <a>safe</a>.
(|>.) :: Buffer %1 -> Char -> Buffer
infixl 6 |>.

-- | Prepend <a>Char</a> to a <a>Buffer</a> by mutating it.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XLinearTypes
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; 'q' .&lt;| 'w' .&lt;| b)
--   "qw"
--   </pre>
--   
--   <b>Warning:</b> In contrast to <a>singleton</a>, it is the
--   responsibility of the caller to sanitize surrogate code points with
--   <a>safe</a>.
(.<|) :: Char -> Buffer %1 -> Buffer
infixr 6 .<|

-- | Prepend a given count of a <a>Char</a> to a <a>Buffer</a>.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XLinearTypes
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; prependChars 3 'x' (b |&gt;. 'A'))
--   "xxxA"
--   </pre>
prependChars :: Word -> Char -> Buffer %1 -> Buffer

-- | Apppend a given count of a <a>Char</a> to a <a>Buffer</a>.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XLinearTypes
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; appendChars 3 'x' (b |&gt;. 'A'))
--   "Axxx"
--   </pre>
appendChars :: Word -> Char -> Buffer %1 -> Buffer

-- | Append <a>Text</a> suffix to a <a>Buffer</a> by mutating it. If a
--   suffix is statically known, consider using <a>(|&gt;#)</a> for optimal
--   performance.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; b |&gt; "foo" |&gt; "bar")
--   "foobar"
--   </pre>
(|>) :: Buffer %1 -> Text -> Buffer
infixl 6 |>

-- | Prepend <a>Text</a> prefix to a <a>Buffer</a> by mutating it. If a
--   prefix is statically known, consider using <a>(#&lt;|)</a> for optimal
--   performance.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; "foo" &lt;| "bar" &lt;| b)
--   "foobar"
--   </pre>
(<|) :: Text -> Buffer %1 -> Buffer
infixr 6 <|

-- | Append given number of spaces.
(|>…) :: Buffer %1 -> Word -> Buffer
infixr 6 |>…

-- | Prepend given number of spaces.
(…<|) :: Word -> Buffer %1 -> Buffer
infixr 6 …<|

-- | Append a null-terminated UTF-8 string to a <a>Buffer</a> by mutating
--   it. E. g.,
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes -XMagicHash
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; b |&gt;# "foo"# |&gt;# "bar"#)
--   "foobar"
--   </pre>
--   
--   The literal string must not contain zero bytes <tt>\NUL</tt> and must
--   be a valid UTF-8, these conditions are not checked.
(|>#) :: Buffer %1 -> Addr# -> Buffer
infixl 6 |>#

-- | Prepend a null-terminated UTF-8 string to a <a>Buffer</a> by mutating
--   it. E. g.,
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes -XMagicHash
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; "foo"# #&lt;| "bar"# #&lt;| b)
--   "foobar"
--   </pre>
--   
--   The literal string must not contain zero bytes <tt>\NUL</tt> and must
--   be a valid UTF-8, these conditions are not checked.
--   
--   <i>Note:</i> When the syntactic extensions <tt>UnboxedTuples</tt> or
--   <tt>UnboxedSums</tt> are enabled, extra spaces are required when using
--   parentheses: i.e. use <tt>( <a>#&lt;|</a> )</tt> instead of
--   <tt>(<a>#&lt;|</a>)</tt>. See the GHC User Guide chapter “<a>Unboxed
--   types and primitive operations</a>” for further information.
(#<|) :: Addr# -> Buffer %1 -> Buffer
infixr 6 #<|

-- | Alias for <tt><a>(#&lt;|)</a></tt>.

-- | <i>Deprecated: Use <a>(#&lt;|)</a> instead</i>
(<|#) :: Addr# -> Buffer %1 -> Buffer
infixr 6 <|#

-- | Pad a builder from the <i>right</i> side to the specified length with
--   the specified character.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XLinearTypes
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; justifyLeft 10 'x' (appendChars 3 'A' b))
--   "AAAxxxxxxx"
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; justifyLeft 5 'x' (appendChars 6 'A' b))
--   "AAAAAA"
--   </pre>
--   
--   Note that <a>newEmptyBuffer</a> is needed in some situations. See
--   <a>justifyRight</a> for an example.
justifyLeft :: Word -> Char -> Buffer %1 -> Buffer

-- | Pad a builder from the <i>left</i> side to the specified length with
--   the specified character.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XLinearTypes
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; justifyRight 10 'x' (appendChars 3 'A' b))
--   "xxxxxxxAAA"
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; justifyRight 5 'x' (appendChars 6 'A' b))
--   "AAAAAA"
--   </pre>
--   
--   Note that <a>newEmptyBuffer</a> is needed in some situations. The
--   following example creates a utility function that justify a text and
--   then append it to a buffer.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes -XUnboxedTuples
--   
--   &gt;&gt;&gt; import Data.Text.Builder.Linear.Buffer
--   
--   &gt;&gt;&gt; import Data.Text (Text)
--   
--   &gt;&gt;&gt; :{
--   appendJustified :: Buffer %1 -&gt; Text -&gt; Buffer
--   appendJustified b t = case newEmptyBuffer b of
--     -- Note that we need to create a new buffer from the text, in order
--     -- to justify only the text and not the input buffer.
--     (# b', empty #) -&gt; b' &gt;&lt; justifyRight 12 ' ' (empty |&gt; t)
--   :}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; runBuffer (\b -&gt; (b |&gt; "Test:") `appendJustified` "AAA" `appendJustified` "BBBBBBB")
--   "Test:         AAA     BBBBBBB"
--   </pre>
justifyRight :: Word -> Char -> Buffer %1 -> Buffer

-- | Center a builder to the specified length with the specified character.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XLinearTypes
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; center 10 'x' (appendChars 3 'A' b))
--   "xxxxAAAxxx"
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; center 5 'x' (appendChars 6 'A' b))
--   "AAAAAA"
--   </pre>
--   
--   Note that <a>newEmptyBuffer</a> is needed in some situations. See
--   <a>justifyRight</a> for an example.
center :: Word -> Char -> Buffer %1 -> Buffer

-- | Append the decimal representation of a <i>bounded</i> integral number.
(|>$) :: (Integral a, FiniteBits a) => Buffer %1 -> a -> Buffer
infixl 6 |>$

-- | Prepend the decimal representation of a <i>bounded</i> integral
--   number.
($<|) :: (Integral a, FiniteBits a) => a -> Buffer %1 -> Buffer
infixr 6 $<|

-- | Append the decimal representation of an <i>unbounded</i> integral
--   number.
(|>$$) :: Integral a => Buffer %1 -> a -> Buffer
infixl 6 |>$$

-- | Prepend the decimal representation of an <i>unbounded</i> integral
--   number.
($$<|) :: Integral a => a -> Buffer %1 -> Buffer
infixr 6 $$<|

-- | Append the lower-case hexadecimal representation of a <i>bounded</i>
--   integral number.
--   
--   Negative numbers are interpreted as their corresponding unsigned
--   number:
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes
--   
--   &gt;&gt;&gt; import Data.Int (Int8, Int16)
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; b |&gt;&amp; (-1 :: Int8)) == "ff"
--   True
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; b |&gt;&amp; (-1 :: Int16)) == "ffff"
--   True
--   </pre>
(|>&) :: (Integral a, FiniteBits a) => Buffer %1 -> a -> Buffer
infixl 6 |>&

-- | Prepend the lower-case hexadecimal representation of a <i>bounded</i>
--   integral number.
--   
--   Negative numbers are interpreted as their corresponding unsigned
--   number:
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XLinearTypes
--   
--   &gt;&gt;&gt; import Data.Int (Int8, Int16)
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; (-1 :: Int8) &amp;&lt;| b) == "ff"
--   True
--   
--   &gt;&gt;&gt; runBuffer (\b -&gt; (-1 :: Int16) &amp;&lt;| b) == "ffff"
--   True
--   </pre>
(&<|) :: (Integral a, FiniteBits a) => a -> Buffer %1 -> Buffer
infixr 6 &<|

-- | Append the decimal representation of a <a>Double</a>.
--   
--   Matches <a>show</a> in displaying in standard or scientific notation:
--   
--   <pre>
--   &gt;&gt;&gt; runBuffer (\b -&gt; b |&gt;% 123.456)
--   "123.456"
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; runBuffer (\b -&gt; b |&gt;% 1.23e7)
--   "1.23e7"
--   </pre>
(|>%) :: Buffer %1 -> Double -> Buffer
infixl 6 |>%

-- | Prepend the decimal representation of a <a>Double</a>.
--   
--   Matches <a>show</a> in displaying in standard or scientific notation
--   (see examples in <tt><a>(|&gt;%)</a></tt>).
(%<|) :: Double -> Buffer %1 -> Buffer
infixr 6 %<|


-- | Builder for strict <a>Text</a> and <a>ByteString</a>, based on linear
--   types. It consistently outperforms <a>Data.Text.Lazy.Builder</a> from
--   <tt>text</tt> as well as a strict builder from <tt>text-builder</tt>,
--   and scales better.
module Data.Text.Builder.Linear

-- | Thin wrapper over <a>Buffer</a> with a handy <a>Semigroup</a>
--   instance.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XMagicHash
--   
--   &gt;&gt;&gt; fromText "foo" &lt;&gt; fromChar '_' &lt;&gt; fromAddr "bar"#
--   "foo_bar"
--   </pre>
--   
--   Remember: this is a strict builder, so on contrary to
--   <a>Data.Text.Lazy.Builder</a> for optimal performance you should use
--   strict left folds instead of lazy right ones.
--   
--   Note that (similar to other builders) concatenation of <a>Builder</a>s
--   allocates thunks. This is to a certain extent mitigated by aggressive
--   inlining, but it is faster to use <a>Buffer</a> directly.
newtype Builder
Builder :: (Buffer %1 -> Buffer) -> Builder
[unBuilder] :: Builder -> Buffer %1 -> Buffer

-- | Run <a>Builder</a> computation on an empty <a>Buffer</a>, returning
--   strict <a>Text</a>.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings -XMagicHash
--   
--   &gt;&gt;&gt; runBuilder (fromText "foo" &lt;&gt; fromChar '_' &lt;&gt; fromAddr "bar"#)
--   "foo_bar"
--   </pre>
--   
--   This function has a polymorphic arrow and thus can be used both in
--   usual and linear contexts.
runBuilder :: forall (m :: Multiplicity). Builder %m -> Text

-- | Same as <a>runBuilder</a>, but returning a UTF-8 encoded strict
--   <a>ByteString</a>.
runBuilderBS :: forall (m :: Multiplicity). Builder %m -> ByteString

-- | Create <a>Builder</a>, containing a given <a>Text</a>.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings
--   
--   &gt;&gt;&gt; fromText "foo" &lt;&gt; fromText "bar"
--   "foobar"
--   </pre>
--   
--   For literal strings it is faster to use <a>fromAddr</a> instead of
--   <a>fromText</a>.
fromText :: Text -> Builder

-- | Create <a>Builder</a>, containing a given <a>Char</a>.
--   
--   <pre>
--   &gt;&gt;&gt; fromChar 'x' &lt;&gt; fromChar 'y'
--   "xy"
--   </pre>
--   
--   In contrast to <a>singleton</a>, it's a responsibility of the caller
--   to sanitize surrogate code points with <a>safe</a>.
fromChar :: Char -> Builder

-- | Create <a>Builder</a>, containing a null-terminated UTF-8 string,
--   specified by <a>Addr#</a>.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XMagicHash
--   
--   &gt;&gt;&gt; fromAddr "foo"# &lt;&gt; fromAddr "bar"#
--   "foobar"
--   </pre>
--   
--   The literal string must not contain zero bytes <tt>\NUL</tt> and must
--   be a valid UTF-8, these conditions are not checked.
fromAddr :: Addr# -> Builder

-- | Create <a>Builder</a>, containing decimal representation of a given
--   <i>bounded</i> integer.
--   
--   <pre>
--   &gt;&gt;&gt; fromChar 'x' &lt;&gt; fromDec (123 :: Int)
--   "x123"
--   </pre>
fromDec :: (Integral a, FiniteBits a) => a -> Builder

-- | Create <a>Builder</a>, containing decimal representation of a given
--   <i>unbounded</i> integer.
--   
--   <pre>
--   &gt;&gt;&gt; fromChar 'x' &lt;&gt; fromUnboundedDec (1e24 :: Integer)
--   "x1000000000000000000000000"
--   </pre>
fromUnboundedDec :: Integral a => a -> Builder

-- | Create <a>Builder</a>, containing hexadecimal representation of a
--   given integer.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XMagicHash
--   
--   &gt;&gt;&gt; fromAddr "0x"# &lt;&gt; fromHex (0x123def :: Int)
--   "0x123def"
--   </pre>
fromHex :: (Integral a, FiniteBits a) => a -> Builder

-- | Create <a>Builder</a>, containing decimal representation of a given
--   <a>Double</a>.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XMagicHash
--   
--   &gt;&gt;&gt; fromAddr "pi="# &lt;&gt; fromDouble pi
--   "pi=3.141592653589793"
--   </pre>
fromDouble :: Double -> Builder
instance GHC.Internal.Data.String.IsString Data.Text.Builder.Linear.Builder
instance GHC.Internal.Base.Monoid Data.Text.Builder.Linear.Builder
instance GHC.Internal.Base.Semigroup Data.Text.Builder.Linear.Builder
instance GHC.Internal.Show.Show Data.Text.Builder.Linear.Builder
