Git Product home page Git Product logo

c-storable-deriving's People

Contributors

hsyl20 avatar ianclarksmith avatar maurer avatar mbg avatar sboosali avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

c-storable-deriving's Issues

Working with StablePtr

This package is great, it really makes working with structs over the FFI easier. In my use-case I want to put a StablePtr inside a struct and return the struct over the FFI. Unfortunately this does not work, as StablePtr a does not instantiate Generic. It results in the following error message if want to create an (orphan) instance.

instance CStorable (StablePtr a)
    /home/alex/allscale/insieme/code/analysis/src/cba/haskell/insieme-hat/src/Insieme/Adapter.hs:253:10: error:
        • No instance for (Generic (StablePtr a))
            arising from a use of ‘c-storable-deriving-0.1.2:Foreign.CStorable.TypeClass.$dmcPeek’
        • In the expression:
            c-storable-deriving-0.1.2:Foreign.CStorable.TypeClass.$dmcPeek
              @StablePtr a
          In an equation for ‘cPeek’:
              cPeek
                = c-storable-deriving-0.1.2:Foreign.CStorable.TypeClass.$dmcPeek
                    @StablePtr a
          In the instance declaration for ‘CStorable (StablePtr a)’

Since Ptr a is an instance of Generic I can cast the StablePtr Ctx.Context to Ptr () and us this as a workaround.

Do you have an idea how I could get a StablePtr into my struct?

Use example

Please consider showing one or two usage examples

Feature Request: example of :+:

Although I can understand not supporting sum types out of the box, as it isn't obvious what those instances should look like, I would find it helpful/useful to have some example code that facilitates automatic derivation of CStorable instances for sum types, perhaps as part of the documentation if not an official part of the library.

Feels a little strange jumping right in to this request, without saying it so let me also add: Thankyou for what you are doing/have done. This is a useful package.

StorableWrap is useless

Am I missing something?
Isn't this instance:

instance (Storable a) => CStorable (StorableWrap a)

completly useless?
Why would I want CStorable if I already have Storable?
It should be other way round:

instance(Generic a, CStorable (Rep a)) => Storable (StorableWrap a)

so I could derive Generic instance for my type, wrap it with StorableWrap and feed it to some function that takes Storable.

Is CStorable really necessary?

Typically when providing these generic implementation packages, you provide top level functions that act as stubs for the actual type class your interested in. I would propose that this:

class CStorable a where
  cPeek              :: Ptr a -> IO a
  default cPeek      :: (Generic a, GCStorable (Rep a)) => Ptr a -> IO a
  cPeek p            = fmap to $ gcPeek 0 (castPtr p)

  cPoke              :: Ptr a -> a -> IO ()
  default cPoke      :: (Generic a, GCStorable (Rep a)) => Ptr a -> a -> IO ()
  cPoke p x          = gcPoke 0 (castPtr p) $ from x

  cAlignment         :: a -> Int
  default cAlignment :: (Generic a, GCStorable (Rep a)) => a -> Int
  cAlignment         = gcAlignment . from

  cSizeOf            :: a -> Int
  default cSizeOf    :: (Generic a, GCStorable (Rep a)) => a -> Int
  cSizeOf            = gcSizeOf 0 . from

Becomes just

gpeek      :: (Generic a, GCStorable (Rep a)) => Ptr a -> IO a
gpeek p            = fmap to $ gcPeek 0 (castPtr p)

gpoke      :: (Generic a, GCStorable (Rep a)) => Ptr a -> a -> IO ()
gpoke p x          = gcPoke 0 (castPtr p) $ from x

galignment :: (Generic a, GCStorable (Rep a)) => a -> Int
galignment         = gcAlignment . from

gsizeOf    :: (Generic a, GCStorable (Rep a)) => a -> Int
gsizeOf            = gcSizeOf 0 . from

Your users would then do

data Foo = Foo { a :: X, b :: Y }
  deriving (Generic)

instance Storable Foo where
  peek = gpeek
  poke = gpoke
  sizeOf = gsizeOf
  alignment = galignment

See https://hackage.haskell.org/package/generic-deriving-1.9.0/docs/Generics-Deriving-Monoid.html for a similar example (note they don't export a copy of the Monoid type class, but just the necessary implementations for the methods).

Wrong offset in datatype with many fields

I have a datatype with 32 fields and the offsets of some of the fields are wrong as is the global cSizeOf the structure.

My data structure:

data ObjT = ObjT Word32 Word32 CString MemoryObject (Ptr ()) Word32 Word32 (Ptr Object) (Ptr Object) (Ptr Object)
                 Word32 (Ptr Object) (Ptr Object) Word32 (Ptr (Ptr Object)) (Ptr Object) (Ptr Object) Int32
                 Word32 (Ptr Object) Word32 (Ptr Object) (Ptr ()) (Ptr ()) (Ptr ()) (Ptr ()) (Ptr ()) (Ptr ())
                 (Ptr (Ptr Distance)) Word32 (Ptr Info) Word32 (Ptr ())

where MemoryObject is a 32 bytes object and Ptr are 8 bytes long. The size in C is 264 with the padding bytes. With cSizeOf it is 280.

I think the problem is that fields are not evaluated from left to right hence some offsets are wrong. From the documentation of Generics:

As :+: and :: are just binary operators, one might ask what happens if the datatype has more than two constructors, or a constructor with more than two fields. The answer is simple: the operators are used several times, to combine all the constructors and fields as needed. However, users /should not rely on a specific nesting strategy/ for :+: and :: being used. The compiler is free to choose any nesting it prefers. (In practice, the current implementation tries to produce a more or less balanced nesting, so that the traversal of the structure of the datatype from the root to a particular component can be performed in logarithmic rather than linear time.)

I will try to submit a patch

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.