aboutsummaryrefslogtreecommitdiff
path: root/src/Data/Vector/Generic/Checked.hs
blob: d173bbffa151d0d6a7f554476179c87b14d22fc2 (plain)
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
{-# LANGUAGE CPP #-}
module Data.Vector.Generic.Checked (
  fromListNChecked,
) where

import qualified Data.Stream.Monadic as Stream
import qualified Data.Vector.Fusion.Bundle.Monadic as VBM
import qualified Data.Vector.Fusion.Bundle.Size as VBS
import qualified Data.Vector.Fusion.Util as VFU
import qualified Data.Vector.Generic as VG

-- for INLINE_FUSED and INLINE_INNER
#include "vector.h"


-- These functions are copied over and lightly edited from the vector and
-- vector-stream packages, and thus inherit their BSD-3-Clause license with:
-- Copyright (c) 2008-2012, Roman Leshchinskiy
--               2020-2022, Alexey Kuleshevich
--               2020-2022, Aleksey Khudyakov
--               2020-2022, Andrew Lelechenko

fromListNChecked :: VG.Vector v a => Int -> [a] -> v a
{-# INLINE fromListNChecked #-}
fromListNChecked n = VG.unstream . bundleFromListNChecked n

bundleFromListNChecked :: Int -> [a] -> VBM.Bundle VFU.Id v a
{-# INLINE_FUSED bundleFromListNChecked #-}
bundleFromListNChecked nTop xsTop
  | nTop < 0 = error "fromListNChecked: length negative"
  | otherwise =
      VBM.fromStream (Stream.Stream step (xsTop, nTop)) (VBS.Max (VFU.delay_inline max nTop 0))
  where
    {-# INLINE_INNER step #-}
    step (xs,n) | n == 0 = case xs of
                             [] -> return Stream.Done
                             _:_ -> error "fromListNChecked: list too long"
    step (x:xs,n)        = return (Stream.Yield x (xs,n-1))
    step ([],_)          = error "fromListNChecked: list too short"