packages feed

croaring-ffi-1.0: src/Data/Bitmap/Roaring/FFI/Bitmap64/BulkContext.hsc

{-| C struct @roaring64_bulk_context_t@ from @roaring/roaring64.h@.
It is the cursor for 'Data.Bitmap.Roaring.FFI.Bitmap64.addBulk', 'Data.Bitmap.Roaring.FFI.Bitmap64.removeBulk' and 'Data.Bitmap.Roaring.FFI.Bitmap64.containsBulk'.

The caller allocates it with 'size' and 'alignment' and zero-fills it before the first use.
A context belongs to one bitmap.
Any other change to that bitmap invalidates the context.
Passing an invalidated context is undefined behaviour.
Zero-fill it again before the next use.
-}
module Data.Bitmap.Roaring.FFI.Bitmap64.BulkContext
  ( BulkContext (..)
  , size
  , alignment
  , with
  ) where

#include <roaring/roaring64.h>

import Foreign.Marshal.Alloc (allocaBytesAligned)
import Foreign.Marshal.Utils (fillBytes)
import Foreign.Ptr (Ptr)
import Foreign.Storable (Storable)

-- | @roaring64_bulk_context_t@ in caller-owned memory.
newtype BulkContext = BulkContext (Ptr BulkContext)
  deriving (Eq, Ord, Show, Storable)

-- | @sizeof(roaring64_bulk_context_t)@
size :: Int
size = #{size roaring64_bulk_context_t}
{-# INLINE size #-}

-- | @alignof(roaring64_bulk_context_t)@
alignment :: Int
alignment = #{alignment roaring64_bulk_context_t}
{-# INLINE alignment #-}

-- | A zero-filled context in temporary memory, valid only during the action.
with :: (BulkContext -> IO a) -> IO a
with action =
  allocaBytesAligned size alignment $ \ptr -> do
    fillBytes ptr 0 size
    action $ BulkContext ptr
{-# INLINE with #-}