packages feed

glib-stopgap-0.1.0.0: src/System/GLib/DoublyLinkedLists.hsc

{-# LANGUAGE LambdaCase #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}

module System.GLib.DoublyLinkedLists (
	-- * TYPE
	GList,

	-- * LIST
	g_list_to_list, g_list_to_prev_next_lists,

	-- * POINTER
	g_list_prev_data_next, g_list_data, g_list_prev, g_list_next,

	-- * FREE
	c_g_list_free ) where

import Foreign.Ptr
import Foreign.Ptr.Misc
import Foreign.Storable

#include <glib.h>

data GList a

g_list_to_list :: Ptr (GList a) -> IO (Maybe [Ptr a])
g_list_to_list = ((uncurry appendReverse <$>) <$>) . g_list_to_prev_next_lists

appendReverse :: [a] -> [a] -> [a]
[] `appendReverse` ys = ys
(x : xs) `appendReverse` ys = xs `appendReverse` (x : ys)

g_list_to_prev_next_lists :: Ptr (GList a) -> IO (Maybe ([Ptr a], [Ptr a]))
g_list_to_prev_next_lists = \case
	NullPtr -> pure Nothing
	p -> Just <$> (
		(,)	<$> (g_list_to_prev_list =<< #{peek GList, prev} p)
			<*> g_list_to_next_list p )

g_list_to_prev_list :: Ptr (GList a) -> IO [Ptr a]
g_list_to_prev_list = \case
	NullPtr -> pure []
	p -> (:)
		<$> #{peek GList, data} p
		<*> (g_list_to_prev_list =<< #{peek GList, prev} p)

g_list_to_next_list :: Ptr (GList a) -> IO [Ptr a]
g_list_to_next_list = \case
	NullPtr -> pure []
	p -> (:)
		<$> #{peek GList, data} p
		<*> (g_list_to_next_list =<< #{peek GList, next} p)

g_list_prev_data_next ::
	Ptr (GList a) -> IO (Maybe (Ptr (GList a), Ptr a, Ptr (GList a)))
g_list_prev_data_next = \case
	NullPtr -> pure Nothing
	p -> (Just <$>) $ (,,)
		<$> #{peek GList, prev} p
		<*> #{peek GList, data} p
		<*> #{peek GList, next} p

g_list_data :: Ptr (GList a) -> IO (Maybe (Ptr a))
g_list_data = \case NullPtr -> pure Nothing; p -> Just <$> #{peek GList, data} p

g_list_prev, g_list_next :: Ptr (GList a) -> IO (Maybe (Ptr (GList a)))
g_list_prev = \case NullPtr -> pure Nothing; p -> Just <$> #{peek GList, prev} p
g_list_next = \case NullPtr -> pure Nothing; p -> Just <$> #{peek GList, next} p

foreign import ccall "g_list_free" c_g_list_free :: Ptr (GList a) -> IO ()