module Data.PrimitiveArray.Index.Outside where import Control.Applicative import Control.DeepSeq (NFData(..)) import Data.Aeson import Data.Binary import Data.Serialize import Data.Vector.Unboxed.Deriving import Data.Vector.Unboxed (Unbox(..)) import GHC.Generics import Test.QuickCheck import Data.PrimitiveArray.Index.Class -- | The 'Outside' wrapper takes an index structure, and provides -- 'IndexStream' functions 'streamUp' and 'streamDown' that work the other -- way around. In particular, for @Outside z@ @streamUp (Outside z) = fmap -- Outside $ streamDown z@ and vice versa. @Index@ functions are unwrapped -- but otherwise work as before. newtype Outside z = O { unO :: z } deriving (Eq,Ord,Read,Show,Generic) derivingUnbox "Outside" [t| forall z . Unbox z => Outside z -> z |] [| unO |] [| O |] instance Binary z => Binary (Outside z) instance Serialize z => Serialize (Outside z) instance ToJSON z => ToJSON (Outside z) instance FromJSON z => FromJSON (Outside z) instance NFData z => NFData (Outside z) where rnf (O z) = rnf z {-# Inline rnf #-} instance Index i => Index (Outside i) where linearIndex (O l) (O h) (O i) = linearIndex l h i {-# INLINE linearIndex #-} smallestLinearIndex (O i) = smallestLinearIndex i {-# INLINE smallestLinearIndex #-} largestLinearIndex (O i) = largestLinearIndex i {-# INLINE largestLinearIndex #-} size (O l) (O h) = size l h {-# INLINE size #-} inBounds (O l) (O h) (O z) = inBounds l h z {-# INLINE inBounds #-} instance IndexStream i => IndexStream (Outside i) where streamUp (O l) (O h) = fmap O $ streamDown l h {-# INLINE streamUp #-} streamDown (O l) (O h) = fmap O $ streamUp l h {-# INLINE streamDown #-} instance Arbitrary z => Arbitrary (Outside z) where arbitrary = O <$> arbitrary shrink (O z) = O <$> shrink z