    {-# LANGUAGE CPP #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE DataKinds #-}
    {-# LANGUAGE LambdaCase #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE TypeApplications #-}

    -- -*-haskell-*-
    --  GIMP Toolkit (GTK) CustomStore TreeModel
    --
    --  Author : Duncan Coutts, Axel Simon
    --
    --  Created: 11 Feburary 2006
    --
    --  Copyright (C) 2005-2016 Duncan Coutts, Axel Simon, Hamish Mackenzie
    --
    --  This library is free software; you can redistribute it and/or
    --  modify it under the terms of the GNU Lesser General Public
    --  License as published by the Free Software Foundation; either
    --  version 2.1 of the License, or (at your option) any later version.
    --
    --  This library is distributed in the hope that it will be useful,
    --  but WITHOUT ANY WARRANTY; without even the implied warranty of
    --  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    --  Lesser General Public License for more details.
    --
    -- |
    -- Stability   : provisional
    -- Portability : portable (depends on GHC)
    --
    -- Standard model to store hierarchical data.
    --
    module Data.GI.Gtk.ModelView.ForestStore (

    -- * Types
      ForestStore(..),

    -- * Constructors
      forestStoreNew,
      forestStoreNewDND,

    -- * Implementation of Interfaces
      forestStoreDefaultDragSourceIface,
      forestStoreDefaultDragDestIface,

    -- * Methods
      forestStoreGetValue,
      forestStoreGetTree,
      forestStoreGetForest,
      forestStoreLookup,

      forestStoreSetValue,

      forestStoreInsert,
      forestStoreInsertTree,
      forestStoreInsertForest,

      forestStoreRemove,
      forestStoreClear,

      forestStoreChange,
      forestStoreChangeM,
      ) where

    import Prelude ()
    import Prelude.Compat
    import Data.Bits
    import Data.Word (Word32)
    import Data.Int (Int32)
    import Data.Maybe ( fromMaybe, isJust )
    import Data.Tree
    import Control.Monad ((>=>), when)
    import Control.Monad.IO.Class (MonadIO(..))
    import Control.Exception (assert)
    import Data.IORef

    import Foreign.ForeignPtr (ForeignPtr)

    import Data.GI.Base.BasicTypes
           (TypedObject(..), ManagedPtr(..), GObject)
    import Data.GI.Base.ManagedPtr (withManagedPtr)
    import Data.GI.Base.Overloading (HasParentTypes, ParentTypes)

    import Data.GI.Gtk.ModelView.Types
    import Data.GI.Gtk.ModelView.CustomStore
           (customStoreGetStamp, customStoreGetPrivate,
            TreeModelIface(..), customStoreNew, DragDestIface(..),
            DragSourceIface(..), CustomStore(..), customStoreInvalidateIters)
    import GI.GObject.Objects.Object (Object(..))
    import GI.Gtk.Interfaces.TreeModel
           (treeModelRowDeleted, treeModelRowInserted,
            treeModelRowChanged, toTreeModel, TreeModel(..), IsTreeModel(..),
            treeModelRowHasChildToggled)
    import GI.Gtk.Functions (treeSetRowDragData, treeGetRowDragData)
    import GI.Gtk.Structs.TreePath
           (TreePath)
    import GI.Gtk.Structs.TreeIter
           (getTreeIterUserData3, getTreeIterUserData2, getTreeIterUserData,
            getTreeIterStamp, setTreeIterUserData3, setTreeIterUserData2,
            setTreeIterUserData, setTreeIterStamp, TreeIter(..))
    import Data.GI.Base (get, new)
    import Unsafe.Coerce (unsafeCoerce)

    --------------------------------------------
    -- internal model data types
    --

    data ForestStoreIter = ForestStoreIter Int32 Word32 Word32 Word32

    fromForestStoreIter :: MonadIO m => ForestStoreIter -> m TreeIter
    fromForestStoreIter :: forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
    fromForestStoreIter (ForestStoreIter Int32
    s Word32
    u1 Word32
    u2 Word32
    u3) = do
        i <- (ManagedPtr TreeIter -> TreeIter)
    -> [AttrOp TreeIter 'AttrSet] -> m TreeIter
    forall a (tag :: AttrOpTag) (m :: * -> *).
    (Constructible a tag, MonadIO m) =>
    (ManagedPtr a -> a) -> [AttrOp a tag] -> m a
    forall (m :: * -> *).
    MonadIO m =>
    (ManagedPtr TreeIter -> TreeIter)
    -> [AttrOp TreeIter 'AttrSet] -> m TreeIter
    new ManagedPtr TreeIter -> TreeIter
    TreeIter []
        setTreeIterStamp     i s
        setTreeIterUserData  i $ unsafeCoerce u1
        setTreeIterUserData2 i $ unsafeCoerce u2
        setTreeIterUserData3 i $ unsafeCoerce u3
        return i

    toForestStoreIter :: MonadIO m => TreeIter -> m ForestStoreIter
    toForestStoreIter :: forall (m :: * -> *). MonadIO m => TreeIter -> m ForestStoreIter
    toForestStoreIter TreeIter
    iter = do
        stamp <- TreeIter -> m Int32
    forall (m :: * -> *). MonadIO m => TreeIter -> m Int32
    getTreeIterStamp TreeIter
    iter
        u1    <- getTreeIterUserData iter
        u2    <- getTreeIterUserData2 iter
        u3    <- getTreeIterUserData3 iter
        return $ ForestStoreIter stamp (unsafeCoerce u1) (unsafeCoerce u2) (unsafeCoerce u3)

    forestStoreIterSetStamp :: ForestStoreIter -> Int32 -> ForestStoreIter
    forestStoreIterSetStamp :: ForestStoreIter -> Int32 -> ForestStoreIter
    forestStoreIterSetStamp (ForestStoreIter Int32
    _ Word32
    a Word32
    b Word32
    c) Int32
    s = Int32 -> Word32 -> Word32 -> Word32 -> ForestStoreIter
    ForestStoreIter Int32
    s Word32
    a Word32
    b Word32
    c

    -- | A store for hierarchical data.
    --
    newtype ForestStore a = ForestStore (ManagedPtr (CustomStore (IORef (Store a)) a))

    mkForestStore :: CustomStore (IORef (Store a)) a -> ForestStore a
    mkForestStore :: forall a. CustomStore (IORef (Store a)) a -> ForestStore a
    mkForestStore (CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
    ptr) = ManagedPtr (CustomStore (IORef (Store a)) a) -> ForestStore a
    forall a.
    ManagedPtr (CustomStore (IORef (Store a)) a) -> ForestStore a
    ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
    ptr

    instance HasParentTypes (ForestStore a)
    type instance ParentTypes (ForestStore a) = '[TreeModel]

    instance TypedObject (ForestStore a) where
      glibType :: IO GType
    glibType = forall a. TypedObject a => IO GType
    glibType @TreeModel

    instance GObject (ForestStore a)

    instance IsTypedTreeModel ForestStore

    -- | Maximum number of nodes on each level.
    --
    -- * These numbers determine how many bits in a 'TreeIter' are devoted to
    --   each level. Hence, these numbers reflect log2 of the maximum number
    --   of nodes at a level, rounded up.
    --
    type Depth = [Int]

    data Store a = Store {
      forall a. Store a -> Depth
    depth :: Depth,
      forall a. Store a -> Cache a
    content :: Cache a
    }

    -- | Create a new list store.
    --
    -- * The given rose tree determines the initial content and may be the empty
    --   list. Each 'Tree' in the forest corresponds to one top-level node.
    --
    -- * The ForestStore maintains the initially given Forest and aligns the 'TreePath'
    --   bits to fit in 96-bit length 'TreeIter' storage.
    --
    -- * Additionally, a cache is used to achieve higher performance if operating on
    --   recently used TreePaths.
    --
    -- * __Note:__ due to the limited amount of bits available in TreeIter storage, only
    --   limited depth forests can be used with this implementation, the result of too deep
    --   Forests is an undefined behaviour while trying to retrieve the deeply nested nodes.
    --   For example: assuming the average requiement is 8 bits per tree level (max number of
    --   children at the level is 255), then we can only use 12 levels deep trees (96/8) -
    --   any further levels in a TreePath will not be encoded in the corresponding TreeIter
    --   storage.
    --
    forestStoreNew :: MonadIO m => Forest a -> m (ForestStore a)
    forestStoreNew :: forall (m :: * -> *) a. MonadIO m => Forest a -> m (ForestStore a)
    forestStoreNew Forest a
    forest = Forest a
    -> Maybe (DragSourceIface ForestStore a)
    -> Maybe (DragDestIface ForestStore a)
    -> m (ForestStore a)
    forall (m :: * -> *) a.
    MonadIO m =>
    Forest a
    -> Maybe (DragSourceIface ForestStore a)
    -> Maybe (DragDestIface ForestStore a)
    -> m (ForestStore a)
    forestStoreNewDND Forest a
    forest
                            (DragSourceIface ForestStore a
    -> Maybe (DragSourceIface ForestStore a)
    forall a. a -> Maybe a
    Just DragSourceIface ForestStore a
    forall row. DragSourceIface ForestStore row
    forestStoreDefaultDragSourceIface)
                            (DragDestIface ForestStore a -> Maybe (DragDestIface ForestStore a)
    forall a. a -> Maybe a
    Just DragDestIface ForestStore a
    forall row. DragDestIface ForestStore row
    forestStoreDefaultDragDestIface)

    -- | Create a new list store.
    --
    -- * In addition to 'forestStoreNew', this function takes an two interfaces
    --   to implement user-defined drag-and-drop functionality.
    --
    forestStoreNewDND :: MonadIO m => Forest a -- ^ the inital tree stored in this model
      -> Maybe (DragSourceIface ForestStore a) -- ^ an optional interface for drags
      -> Maybe (DragDestIface ForestStore a) -- ^ an optional interface to handle drops
      -> m (ForestStore a)
    forestStoreNewDND :: forall (m :: * -> *) a.
    MonadIO m =>
    Forest a
    -> Maybe (DragSourceIface ForestStore a)
    -> Maybe (DragDestIface ForestStore a)
    -> m (ForestStore a)
    forestStoreNewDND Forest a
    forest Maybe (DragSourceIface ForestStore a)
    mDSource Maybe (DragDestIface ForestStore a)
    mDDest = IO (ForestStore a) -> m (ForestStore a)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (ForestStore a) -> m (ForestStore a))
    -> IO (ForestStore a) -> m (ForestStore a)
    forall a b. (a -> b) -> a -> b
    $ do
      (storeRef :: IORef (Store a)) <- Store a -> IO (IORef (Store a))
    forall a. a -> IO (IORef a)
    newIORef Store {
          depth :: Depth
    depth = Forest a -> Depth
    forall a. Forest a -> Depth
    calcForestDepth Forest a
    forest,
          content :: Cache a
    content = Forest a -> Cache a
    forall a. Forest a -> Cache a
    storeToCache Forest a
    forest
        }
      let withStore :: (Store a -> IO result) -> IO result
          withStore Store a -> IO result
    f = IORef (Store a) -> IO (Store a)
    forall a. IORef a -> IO a
    readIORef IORef (Store a)
    storeRef IO (Store a) -> (Store a -> IO result) -> IO result
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Store a -> IO result
    f
          withStoreUpdateCache :: (Store a -> (result, Cache a)) -> IO result
          withStoreUpdateCache Store a -> (result, Cache a)
    f = do
            store <- IORef (Store a) -> IO (Store a)
    forall a. IORef a -> IO a
    readIORef IORef (Store a)
    storeRef
            let (result, cache') = f store
            writeIORef storeRef store { content = cache' }
            return result

      customStoreNew storeRef mkForestStore TreeModelIface {
        treeModelIfaceGetFlags = return [],

        treeModelIfaceGetIter = \TreePath
    path -> (Store a -> IO (Maybe TreeIter)) -> IO (Maybe TreeIter)
    forall result. (Store a -> IO result) -> IO result
    withStore ((Store a -> IO (Maybe TreeIter)) -> IO (Maybe TreeIter))
    -> (Store a -> IO (Maybe TreeIter)) -> IO (Maybe TreeIter)
    forall a b. (a -> b) -> a -> b
    $
          \Store { depth :: forall a. Store a -> Depth
    depth = Depth
    d } -> Depth -> [Int32] -> Maybe ForestStoreIter
    fromPath Depth
    d ([Int32] -> Maybe ForestStoreIter)
    -> IO [Int32] -> IO (Maybe ForestStoreIter)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> TreePath -> IO [Int32]
    forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
    treePathGetIndices' TreePath
    path IO (Maybe ForestStoreIter)
    -> (Maybe ForestStoreIter -> IO (Maybe TreeIter))
    -> IO (Maybe TreeIter)
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (ForestStoreIter -> IO TreeIter)
    -> Maybe ForestStoreIter -> IO (Maybe TreeIter)
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Maybe a -> m (Maybe b)
    mapM ForestStoreIter -> IO TreeIter
    forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
    fromForestStoreIter,

        treeModelIfaceGetPath = toForestStoreIter >=> \ForestStoreIter
    iter -> (Store a -> IO TreePath) -> IO TreePath
    forall result. (Store a -> IO result) -> IO result
    withStore ((Store a -> IO TreePath) -> IO TreePath)
    -> (Store a -> IO TreePath) -> IO TreePath
    forall a b. (a -> b) -> a -> b
    $
          \Store { depth :: forall a. Store a -> Depth
    depth = Depth
    d } -> [Int32] -> IO TreePath
    forall (m :: * -> *). MonadIO m => [Int32] -> m TreePath
    treePathNewFromIndices' ([Int32] -> IO TreePath) -> [Int32] -> IO TreePath
    forall a b. (a -> b) -> a -> b
    $ Depth -> ForestStoreIter -> [Int32]
    toPath Depth
    d ForestStoreIter
    iter,

        treeModelIfaceGetRow  = toForestStoreIter >=> \ForestStoreIter
    iter -> (Store a -> (a, Cache a)) -> IO a
    forall result. (Store a -> (result, Cache a)) -> IO result
    withStoreUpdateCache ((Store a -> (a, Cache a)) -> IO a)
    -> (Store a -> (a, Cache a)) -> IO a
    forall a b. (a -> b) -> a -> b
    $
          \Store { depth :: forall a. Store a -> Depth
    depth = Depth
    d, content :: forall a. Store a -> Cache a
    content = Cache a
    cache } ->
            case Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    checkSuccess Depth
    d ForestStoreIter
    iter Cache a
    cache of
              (Bool
    True, cache' :: Cache a
    cache'@((ForestStoreIter
    _, (Node { rootLabel :: forall a. Tree a -> a
    rootLabel = a
    val }:Forest a
    _)):Cache a
    _)) ->
                (a
    val, Cache a
    cache')
              (Bool, Cache a)
    _ -> [Char] -> (a, Cache a)
    forall a. (?callStack::CallStack) => [Char] -> a
    error [Char]
    "ForestStore.getRow: iter does not refer to a valid entry",

        treeModelIfaceIterNext = toForestStoreIter >=> \ForestStoreIter
    iter -> (Store a -> (Maybe ForestStoreIter, Cache a))
    -> IO (Maybe ForestStoreIter)
    forall result. (Store a -> (result, Cache a)) -> IO result
    withStoreUpdateCache (
          \Store { depth :: forall a. Store a -> Depth
    depth = Depth
    d, content :: forall a. Store a -> Cache a
    content = Cache a
    cache } -> Depth
    -> ForestStoreIter -> Cache a -> (Maybe ForestStoreIter, Cache a)
    forall a.
    Depth
    -> ForestStoreIter -> Cache a -> (Maybe ForestStoreIter, Cache a)
    iterNext Depth
    d ForestStoreIter
    iter Cache a
    cache) IO (Maybe ForestStoreIter)
    -> (Maybe ForestStoreIter -> IO (Maybe TreeIter))
    -> IO (Maybe TreeIter)
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (ForestStoreIter -> IO TreeIter)
    -> Maybe ForestStoreIter -> IO (Maybe TreeIter)
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Maybe a -> m (Maybe b)
    mapM ForestStoreIter -> IO TreeIter
    forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
    fromForestStoreIter,

        treeModelIfaceIterChildren = \Maybe TreeIter
    mIter -> do
            iter <- IO ForestStoreIter
    -> (TreeIter -> IO ForestStoreIter)
    -> Maybe TreeIter
    -> IO ForestStoreIter
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (ForestStoreIter -> IO ForestStoreIter
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ForestStoreIter
    invalidIter) TreeIter -> IO ForestStoreIter
    forall (m :: * -> *). MonadIO m => TreeIter -> m ForestStoreIter
    toForestStoreIter Maybe TreeIter
    mIter
            withStoreUpdateCache (
              \Store { depth :: forall a. Store a -> Depth
    depth = Depth
    d, content :: forall a. Store a -> Cache a
    content = Cache a
    cache } ->
                Depth
    -> Int
    -> ForestStoreIter
    -> Cache a
    -> (Maybe ForestStoreIter, Cache a)
    forall a.
    Depth
    -> Int
    -> ForestStoreIter
    -> Cache a
    -> (Maybe ForestStoreIter, Cache a)
    iterNthChild Depth
    d Int
    0 ForestStoreIter
    iter Cache a
    cache) >>= mapM fromForestStoreIter,

        treeModelIfaceIterHasChild = toForestStoreIter >=> \ForestStoreIter
    iter -> (Store a -> (Bool, Cache a)) -> IO Bool
    forall result. (Store a -> (result, Cache a)) -> IO result
    withStoreUpdateCache ((Store a -> (Bool, Cache a)) -> IO Bool)
    -> (Store a -> (Bool, Cache a)) -> IO Bool
    forall a b. (a -> b) -> a -> b
    $
          \Store { depth :: forall a. Store a -> Depth
    depth = Depth
    d, content :: forall a. Store a -> Cache a
    content = Cache a
    cache } ->
           let (Maybe ForestStoreIter
    mIter, Cache a
    cache') = Depth
    -> Int
    -> ForestStoreIter
    -> Cache a
    -> (Maybe ForestStoreIter, Cache a)
    forall a.
    Depth
    -> Int
    -> ForestStoreIter
    -> Cache a
    -> (Maybe ForestStoreIter, Cache a)
    iterNthChild Depth
    d Int
    0 ForestStoreIter
    iter Cache a
    cache
            in (Maybe ForestStoreIter -> Bool
    forall a. Maybe a -> Bool
    isJust Maybe ForestStoreIter
    mIter, Cache a
    cache'),

        treeModelIfaceIterNChildren = mapM toForestStoreIter >=> \Maybe ForestStoreIter
    mIter -> (Store a -> (Int, Cache a)) -> IO Int
    forall result. (Store a -> (result, Cache a)) -> IO result
    withStoreUpdateCache ((Store a -> (Int, Cache a)) -> IO Int)
    -> (Store a -> (Int, Cache a)) -> IO Int
    forall a b. (a -> b) -> a -> b
    $
          \Store { depth :: forall a. Store a -> Depth
    depth = Depth
    d, content :: forall a. Store a -> Cache a
    content = Cache a
    cache } ->
          let iter :: ForestStoreIter
    iter = ForestStoreIter -> Maybe ForestStoreIter -> ForestStoreIter
    forall a. a -> Maybe a -> a
    fromMaybe ForestStoreIter
    invalidIter Maybe ForestStoreIter
    mIter
           in Depth -> ForestStoreIter -> Cache a -> (Int, Cache a)
    forall a. Depth -> ForestStoreIter -> Cache a -> (Int, Cache a)
    iterNChildren Depth
    d ForestStoreIter
    iter Cache a
    cache,

        treeModelIfaceIterNthChild = \Maybe TreeIter
    mIter Int
    idx  -> do
            iter <- IO ForestStoreIter
    -> (TreeIter -> IO ForestStoreIter)
    -> Maybe TreeIter
    -> IO ForestStoreIter
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (ForestStoreIter -> IO ForestStoreIter
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ForestStoreIter
    invalidIter) TreeIter -> IO ForestStoreIter
    forall (m :: * -> *). MonadIO m => TreeIter -> m ForestStoreIter
    toForestStoreIter Maybe TreeIter
    mIter
            withStoreUpdateCache (
              \Store { depth :: forall a. Store a -> Depth
    depth = Depth
    d, content :: forall a. Store a -> Cache a
    content = Cache a
    cache } ->
                Depth
    -> Int
    -> ForestStoreIter
    -> Cache a
    -> (Maybe ForestStoreIter, Cache a)
    forall a.
    Depth
    -> Int
    -> ForestStoreIter
    -> Cache a
    -> (Maybe ForestStoreIter, Cache a)
    iterNthChild Depth
    d Int
    idx ForestStoreIter
    iter Cache a
    cache) >>= mapM fromForestStoreIter,

        treeModelIfaceIterParent = toForestStoreIter >=> \ForestStoreIter
    iter -> (Store a -> IO (Maybe TreeIter)) -> IO (Maybe TreeIter)
    forall result. (Store a -> IO result) -> IO result
    withStore ((Store a -> IO (Maybe TreeIter)) -> IO (Maybe TreeIter))
    -> (Store a -> IO (Maybe TreeIter)) -> IO (Maybe TreeIter)
    forall a b. (a -> b) -> a -> b
    $
          \Store { depth :: forall a. Store a -> Depth
    depth = Depth
    d } -> (ForestStoreIter -> IO TreeIter)
    -> Maybe ForestStoreIter -> IO (Maybe TreeIter)
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Maybe a -> m (Maybe b)
    mapM ForestStoreIter -> IO TreeIter
    forall (m :: * -> *). MonadIO m => ForestStoreIter -> m TreeIter
    fromForestStoreIter (Depth -> ForestStoreIter -> Maybe ForestStoreIter
    iterParent Depth
    d ForestStoreIter
    iter),

        treeModelIfaceRefNode = \TreeIter
    _ -> () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (),
        treeModelIfaceUnrefNode = \TreeIter
    _ -> () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
       } mDSource mDDest

    -- | Default drag functions for
    -- 'Data.GI.Gtk.ModelView.ForestStore'. These functions allow the rows of
    -- the model to serve as drag source. Any row is allowed to be dragged and the
    -- data set in the 'SelectionDataM' object is set with 'treeSetRowDragData',
    -- i.e. it contains the model and the 'TreePath' to the row.
    forestStoreDefaultDragSourceIface :: DragSourceIface ForestStore row
    forestStoreDefaultDragSourceIface :: forall row. DragSourceIface ForestStore row
    forestStoreDefaultDragSourceIface = DragSourceIface {
        customDragSourceRowDraggable :: ForestStore row -> TreePath -> IO Bool
    customDragSourceRowDraggable = \ForestStore row
    _ TreePath
    _-> Bool -> IO Bool
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True,
        customDragSourceDragDataGet :: ForestStore row -> TreePath -> SelectionData -> IO Bool
    customDragSourceDragDataGet = \ForestStore row
    model TreePath
    path SelectionData
    sel -> SelectionData -> ForestStore row -> TreePath -> IO Bool
    forall (m :: * -> *) a.
    (?callStack::CallStack, MonadIO m, IsTreeModel a) =>
    SelectionData -> a -> TreePath -> m Bool
    treeSetRowDragData SelectionData
    sel ForestStore row
    model TreePath
    path,
        customDragSourceDragDataDelete :: ForestStore row -> TreePath -> IO Bool
    customDragSourceDragDataDelete = \ForestStore row
    model TreePath
    path -> TreePath -> IO [Int32]
    forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
    treePathGetIndices' TreePath
    path IO [Int32] -> ([Int32] -> IO Bool) -> IO Bool
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \dest :: [Int32]
    dest@(Int32
    _:[Int32]
    _) -> do
                IO Bool -> IO Bool
    forall a. IO a -> IO a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO Bool -> IO Bool) -> IO Bool -> IO Bool
    forall a b. (a -> b) -> a -> b
    $ ForestStore row -> TreePath -> IO Bool
    forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> m Bool
    forestStoreRemove ForestStore row
    model TreePath
    path
                Bool -> IO Bool
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True

      }

    -- | Default drop functions for 'Data.GI.Gtk.ModelView.ForestStore'. These
    --   functions accept a row and insert the row into the new location if it is
    --   dragged into a tree view
    -- that uses the same model.
    forestStoreDefaultDragDestIface :: DragDestIface ForestStore row
    forestStoreDefaultDragDestIface :: forall row. DragDestIface ForestStore row
    forestStoreDefaultDragDestIface = DragDestIface {
        customDragDestRowDropPossible :: ForestStore row -> TreePath -> SelectionData -> IO Bool
    customDragDestRowDropPossible = \ForestStore row
    model TreePath
    path SelectionData
    sel -> do
          mModelPath <- SelectionData -> IO (Bool, Maybe TreeModel, Maybe TreePath)
    forall (m :: * -> *).
    (?callStack::CallStack, MonadIO m) =>
    SelectionData -> m (Bool, Maybe TreeModel, Maybe TreePath)
    treeGetRowDragData SelectionData
    sel
          case mModelPath of
            (Bool
    True, Just TreeModel
    model', Maybe TreePath
    source) -> do
                tm <- ForestStore row -> IO TreeModel
    forall (m :: * -> *) o.
    (MonadIO m, IsTreeModel o) =>
    o -> m TreeModel
    toTreeModel ForestStore row
    model
                withManagedPtr tm $ \Ptr TreeModel
    m ->
                    TreeModel -> (Ptr TreeModel -> IO Bool) -> IO Bool
    forall a c.
    (?callStack::CallStack, ManagedPtrNewtype a) =>
    a -> (Ptr a -> IO c) -> IO c
    withManagedPtr TreeModel
    model' ((Ptr TreeModel -> IO Bool) -> IO Bool)
    -> (Ptr TreeModel -> IO Bool) -> IO Bool
    forall a b. (a -> b) -> a -> b
    $ \Ptr TreeModel
    m' -> Bool -> IO Bool
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Ptr TreeModel
    mPtr TreeModel -> Ptr TreeModel -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Ptr TreeModel
    m')
            (Bool, Maybe TreeModel, Maybe TreePath)
    _ -> Bool -> IO Bool
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False,
        customDragDestDragDataReceived :: ForestStore row -> TreePath -> SelectionData -> IO Bool
    customDragDestDragDataReceived = \ForestStore row
    model TreePath
    path SelectionData
    sel -> do
          dest@(_:_) <- TreePath -> IO [Int32]
    forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
    treePathGetIndices' TreePath
    path
          mModelPath <- treeGetRowDragData sel
          case mModelPath of
            (Bool
    True, Just TreeModel
    model', Just TreePath
    path) -> do
              source@(_:_) <- TreePath -> IO [Int32]
    forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
    treePathGetIndices' TreePath
    path
              tm <- toTreeModel model
              withManagedPtr tm $ \Ptr TreeModel
    m ->
                TreeModel -> (Ptr TreeModel -> IO Bool) -> IO Bool
    forall a c.
    (?callStack::CallStack, ManagedPtrNewtype a) =>
    a -> (Ptr a -> IO c) -> IO c
    withManagedPtr TreeModel
    model' ((Ptr TreeModel -> IO Bool) -> IO Bool)
    -> (Ptr TreeModel -> IO Bool) -> IO Bool
    forall a b. (a -> b) -> a -> b
    $ \Ptr TreeModel
    m' ->
                  if Ptr TreeModel
    mPtr TreeModel -> Ptr TreeModel -> Bool
    forall a. Eq a => a -> a -> Bool
    /=Ptr TreeModel
    m' then Bool -> IO Bool
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False
                  else do
                    row <- ForestStore row -> TreePath -> IO (Tree row)
    forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> m (Tree a)
    forestStoreGetTree ForestStore row
    model (TreePath -> IO (Tree row)) -> IO TreePath -> IO (Tree row)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< [Int32] -> IO TreePath
    forall (m :: * -> *). MonadIO m => [Int32] -> m TreePath
    treePathNewFromIndices' [Int32]
    source
                    initPath <- treePathNewFromIndices' (init dest)
                    forestStoreInsertTree model initPath (fromIntegral $ last dest) row
                    return True
            (Bool, Maybe TreeModel, Maybe TreePath)
    _ -> Bool -> IO Bool
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False
      }

    --------------------------------------------
    -- low level bit-twiddling utility functions
    --

    bitsNeeded :: Word32 -> Int
    bitsNeeded :: Word32 -> Int
    bitsNeeded Word32
    n = Int -> Word32 -> Int
    forall {t} {t}. (Num t, Num t, Bits t) => t -> t -> t
    bitsNeeded' Int
    0 Word32
    n
      where bitsNeeded' :: t -> t -> t
    bitsNeeded' t
    b t
    0 = t
    b
            bitsNeeded' t
    b t
    n = t -> t -> t
    bitsNeeded' (t
    bt -> t -> t
    forall a. Num a => a -> a -> a
    +t
    1) (t
    n t -> Int -> t
    forall a. Bits a => a -> Int -> a
    `shiftR` Int
    1)

    getBitSlice :: ForestStoreIter -> Int -> Int -> Word32
    getBitSlice :: ForestStoreIter -> Int -> Int -> Word32
    getBitSlice (ForestStoreIter Int32
    _ Word32
    a Word32
    b Word32
    c) Int
    off Int
    count =
          Word32 -> Int -> Int -> Word32
    getBitSliceWord Word32
    a  Int
    off     Int
    count
      Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .|. Word32 -> Int -> Int -> Word32
    getBitSliceWord Word32
    b (Int
    offInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    32) Int
    count
      Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .|. Word32 -> Int -> Int -> Word32
    getBitSliceWord Word32
    c (Int
    offInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    64) Int
    count

      where getBitSliceWord :: Word32 -> Int -> Int -> Word32
            getBitSliceWord :: Word32 -> Int -> Int -> Word32
    getBitSliceWord Word32
    word Int
    off Int
    count =
              Word32
    word Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shift` (-Int
    off) Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .&. (Word32
    1 Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shiftL` Int
    count Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    - Word32
    1)

    setBitSlice :: ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
    setBitSlice :: ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
    setBitSlice (ForestStoreIter Int32
    stamp Word32
    a Word32
    b Word32
    c) Int
    off Int
    count Word32
    value =
      Bool -> ForestStoreIter -> ForestStoreIter
    forall a. (?callStack::CallStack) => Bool -> a -> a
    assert (Word32
    value Word32 -> Word32 -> Bool
    forall a. Ord a => a -> a -> Bool
    < Word32
    1 Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shiftL` Int
    count) (ForestStoreIter -> ForestStoreIter)
    -> ForestStoreIter -> ForestStoreIter
    forall a b. (a -> b) -> a -> b
    $
      Int32 -> Word32 -> Word32 -> Word32 -> ForestStoreIter
    ForestStoreIter Int32
    stamp
                    (Word32 -> Int -> Int -> Word32 -> Word32
    setBitSliceWord Word32
    a  Int
    off     Int
    count Word32
    value)
                    (Word32 -> Int -> Int -> Word32 -> Word32
    setBitSliceWord Word32
    b (Int
    offInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    32) Int
    count Word32
    value)
                    (Word32 -> Int -> Int -> Word32 -> Word32
    setBitSliceWord Word32
    c (Int
    offInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    64) Int
    count Word32
    value)

      where setBitSliceWord :: Word32 -> Int -> Int -> Word32 -> Word32
            setBitSliceWord :: Word32 -> Int -> Int -> Word32 -> Word32
    setBitSliceWord Word32
    word Int
    off Int
    count Word32
    value =
              let mask :: Word32
    mask = (Word32
    1 Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shiftL` Int
    count Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    - Word32
    1) Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shift` Int
    off
               in (Word32
    word Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .&. Word32 -> Word32
    forall a. Bits a => a -> a
    complement Word32
    mask) Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .|. (Word32
    value Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shift` Int
    off)

    --iterPrefixEqual :: TreeIter -> TreeIter -> Int -> Bool
    --iterPrefixEqual (TreeIter _ a1 b1 c1) (TreeIter _ a2 b2 c2) pos
    --  | pos>64 = let mask = 1 `shiftL` (pos-64) - 1 in
    --             a1==a2 && b1==b2 && (c1 .&. mask) == (c2 .&. mask)
    --  | pos>32 = let mask = 1 `shiftL` (pos-32) - 1 in
    --             a1==a2 && (b1 .&. mask) == (b2 .&. mask)
    --  | otherwise = let mask = 1 `shiftL` pos - 1 in
    --                (a1 .&. mask) == (a2 .&. mask)

    -- | The invalid tree iterator.
    --
    invalidIter :: ForestStoreIter
    invalidIter :: ForestStoreIter
    invalidIter = Int32 -> Word32 -> Word32 -> Word32 -> ForestStoreIter
    ForestStoreIter Int32
    0 Word32
    0 Word32
    0 Word32
    0

    --showIterBits (TreeIter _ a b c) = [showBits a, showBits b, showBits c]
    --
    --showBits :: Bits a => a -> String
    --showBits a = [ if testBit a i then '1' else '0' | i <- [0..bitSize a - 1] ]

    -- | Calculate the maximum number of nodes on a per-level basis.
    --
    calcForestDepth :: Forest a -> Depth
    calcForestDepth :: forall a. Forest a -> Depth
    calcForestDepth Forest a
    f = (Word32 -> Int) -> [Word32] -> Depth
    forall a b. (a -> b) -> [a] -> [b]
    map Word32 -> Int
    bitsNeeded ([Word32] -> Depth) -> [Word32] -> Depth
    forall a b. (a -> b) -> a -> b
    $
                        (Word32 -> Bool) -> [Word32] -> [Word32]
    forall a. (a -> Bool) -> [a] -> [a]
    takeWhile (Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    /=Word32
    0) ([Word32] -> [Word32]) -> [Word32] -> [Word32]
    forall a b. (a -> b) -> a -> b
    $
                        (Tree a -> [Word32] -> [Word32])
    -> [Word32] -> Forest a -> [Word32]
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr Tree a -> [Word32] -> [Word32]
    forall {a} {a}. (Num a, Ord a) => Tree a -> [a] -> [a]
    calcTreeDepth (Word32 -> [Word32]
    forall a. a -> [a]
    repeat Word32
    0) Forest a
    f
      where
      calcTreeDepth :: Tree a -> [a] -> [a]
    calcTreeDepth Node { subForest :: forall a. Tree a -> [Tree a]
    subForest = [Tree a]
    f } (a
    d:[a]
    ds) =
          (a
    da -> a -> a
    forall a. Num a => a -> a -> a
    +a
    1)a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : (a -> a -> a) -> [a] -> [a] -> [a]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith a -> a -> a
    forall a. Ord a => a -> a -> a
    max [a]
    ds ((Tree a -> [a] -> [a]) -> [a] -> [Tree a] -> [a]
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr Tree a -> [a] -> [a]
    calcTreeDepth (a -> [a]
    forall a. a -> [a]
    repeat a
    0) [Tree a]
    f)

    -- | Convert an iterator into a path.
    --
    toPath :: Depth -> ForestStoreIter -> [Int32]
    toPath :: Depth -> ForestStoreIter -> [Int32]
    toPath Depth
    d ForestStoreIter
    iter = Int -> Depth -> [Int32]
    gP Int
    0 Depth
    d
      where
      gP :: Int -> Depth -> [Int32]
    gP Int
    pos [] = []
      gP Int
    pos (Int
    d:Depth
    ds) = let idx :: Word32
    idx = ForestStoreIter -> Int -> Int -> Word32
    getBitSlice ForestStoreIter
    iter Int
    pos Int
    d in
                      if Word32
    idxWord32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Word32
    0 then [] else Word32 -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word32
    idxWord32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    -Word32
    1) Int32 -> [Int32] -> [Int32]
    forall a. a -> [a] -> [a]
    : Int -> Depth -> [Int32]
    gP (Int
    posInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    d) Depth
    ds

    -- | Try to convert a path into a 'TreeIter'.
    --
    fromPath :: Depth -> [Int32] -> Maybe ForestStoreIter
    fromPath :: Depth -> [Int32] -> Maybe ForestStoreIter
    fromPath = Int -> ForestStoreIter -> Depth -> [Int32] -> Maybe ForestStoreIter
    forall {a}.
    Integral a =>
    Int -> ForestStoreIter -> Depth -> [a] -> Maybe ForestStoreIter
    fP Int
    0 ForestStoreIter
    invalidIter
      where
      fP :: Int -> ForestStoreIter -> Depth -> [a] -> Maybe ForestStoreIter
    fP Int
    pos ForestStoreIter
    ti Depth
    _ [] = ForestStoreIter -> Maybe ForestStoreIter
    forall a. a -> Maybe a
    Just ForestStoreIter
    ti -- the remaining bits are zero anyway
      fP Int
    pos ForestStoreIter
    ti [] [a]
    _ = Maybe ForestStoreIter
    forall a. Maybe a
    Nothing
      fP Int
    pos ForestStoreIter
    ti (Int
    d:Depth
    ds) (a
    p:[a]
    ps) = let idx :: Word32
    idx = a -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (a
    pa -> a -> a
    forall a. Num a => a -> a -> a
    +a
    1) in
        if Word32
    idx Word32 -> Word32 -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int -> Word32
    forall a. Bits a => Int -> a
    bit Int
    d then Maybe ForestStoreIter
    forall a. Maybe a
    Nothing else
        Int -> ForestStoreIter -> Depth -> [a] -> Maybe ForestStoreIter
    fP (Int
    posInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    d) (ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
    setBitSlice ForestStoreIter
    ti Int
    pos Int
    d Word32
    idx) Depth
    ds [a]
    ps

    -- | The 'Cache' type synonym is only used iternally. What it represents
    --   the stack during a (fictional) lookup operations.
    --   The topmost frame is the node
    --   for which this lookup was started and the innermost frame (the last
    --   element of the list) contains the root of the tree.
    --
    type Cache a = [(ForestStoreIter, Forest a)]

    -- | Create a traversal structure that allows a pre-order traversal in linear
    --   time.
    --
    -- * The returned structure points at the root of the first level which doesn't
    --   really exist, but serves to indicate that it is before the very first
    --   node.
    --
    storeToCache :: Forest a -> Cache a
    storeToCache :: forall a. Forest a -> Cache a
    storeToCache [] = []
    storeToCache [Tree a]
    forest = [(ForestStoreIter
    invalidIter, [a -> [Tree a] -> Tree a
    forall a. a -> [Tree a] -> Tree a
    Node a
    forall {a}. a
    root [Tree a]
    forest])]
      where
      root :: a
    root = [Char] -> a
    forall a. (?callStack::CallStack) => [Char] -> a
    error [Char]
    "ForestStore.storeToCache: accessed non-exitent root of tree"

    -- | Extract the store from the cache data structure.
    cacheToStore :: Cache a -> Forest a
    cacheToStore :: forall a. Cache a -> Forest a
    cacheToStore [] = []
    cacheToStore [(ForestStoreIter, Forest a)]
    cache = case [(ForestStoreIter, Forest a)] -> (ForestStoreIter, Forest a)
    forall a. (?callStack::CallStack) => [a] -> a
    last [(ForestStoreIter, Forest a)]
    cache of (ForestStoreIter
    _, [Node a
    _ Forest a
    forest]) -> Forest a
    forest

    -- | Advance the traversal structure to the given 'TreeIter'.
    --
    advanceCache :: Depth -> ForestStoreIter -> Cache a -> Cache a
    advanceCache :: forall a. Depth -> ForestStoreIter -> Cache a -> Cache a
    advanceCache Depth
    depth ForestStoreIter
    goal [] = []
    advanceCache Depth
    depth ForestStoreIter
    goal cache :: [(ForestStoreIter, Forest a)]
    cache@((ForestStoreIter
    rootIter,Forest a
    _):[(ForestStoreIter, Forest a)]
    _) =
      Int -> Depth -> [(ForestStoreIter, Forest a)]
    moveToSameLevel Int
    0 Depth
    depth
      where
      moveToSameLevel :: Int -> Depth -> [(ForestStoreIter, Forest a)]
    moveToSameLevel Int
    pos [] = [(ForestStoreIter, Forest a)]
    cache
      moveToSameLevel Int
    pos (Int
    d:Depth
    ds) =
        let
          goalIdx :: Word32
    goalIdx = ForestStoreIter -> Int -> Int -> Word32
    getBitSlice ForestStoreIter
    goal Int
    pos Int
    d
          curIdx :: Word32
    curIdx = ForestStoreIter -> Int -> Int -> Word32
    getBitSlice ForestStoreIter
    rootIter Int
    pos Int
    d
          isNonZero :: Int -> Int -> (ForestStoreIter, b) -> Bool
    isNonZero Int
    pos Int
    d (ForestStoreIter
    ti,b
    _) = ForestStoreIter -> Int -> Int -> Word32
    getBitSlice ForestStoreIter
    ti Int
    pos Int
    dWord32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    /=Word32
    0
        in
        if Word32
    goalIdxWord32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Word32
    curIdx then Int -> Depth -> [(ForestStoreIter, Forest a)]
    moveToSameLevel (Int
    posInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    d) Depth
    ds else
        if Word32
    goalIdxWord32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Word32
    0 then ((ForestStoreIter, Forest a) -> Bool)
    -> [(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)]
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile (Int -> Int -> (ForestStoreIter, Forest a) -> Bool
    forall {b}. Int -> Int -> (ForestStoreIter, b) -> Bool
    isNonZero Int
    pos Int
    d) [(ForestStoreIter, Forest a)]
    cache else
        if Word32
    curIdxWord32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Word32
    0 then Int
    -> Depth
    -> [(ForestStoreIter, Forest a)]
    -> [(ForestStoreIter, Forest a)]
    forall a. Int -> Depth -> Cache a -> Cache a
    moveToChild Int
    pos (Int
    dInt -> Depth -> Depth
    forall a. a -> [a] -> [a]
    :Depth
    ds) [(ForestStoreIter, Forest a)]
    cache else
        if Word32
    goalIdxWord32 -> Word32 -> Bool
    forall a. Ord a => a -> a -> Bool
    <Word32
    curIdx then
          Int
    -> Depth
    -> [(ForestStoreIter, Forest a)]
    -> [(ForestStoreIter, Forest a)]
    forall a. Int -> Depth -> Cache a -> Cache a
    moveToChild Int
    pos (Int
    dInt -> Depth -> Depth
    forall a. a -> [a] -> [a]
    :Depth
    ds) (((ForestStoreIter, Forest a) -> Bool)
    -> [(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)]
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile (Int -> Int -> (ForestStoreIter, Forest a) -> Bool
    forall {b}. Int -> Int -> (ForestStoreIter, b) -> Bool
    isNonZero Int
    pos Int
    d) [(ForestStoreIter, Forest a)]
    cache)
        else let
          -- advance the current iterator to coincide with the goal iterator
          -- at this level
          moveWithinLevel :: Int
    -> Int
    -> [(ForestStoreIter, Forest a)]
    -> [(ForestStoreIter, Forest a)]
    moveWithinLevel Int
    pos Int
    d ((ForestStoreIter
    ti,Forest a
    forest):[(ForestStoreIter, Forest a)]
    parents) = let
              diff :: Int
    diff = Word32 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word32
    goalIdxWord32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    -Word32
    curIdx)
              (Forest a
    dropped, Forest a
    remain) = Int -> Forest a -> (Forest a, Forest a)
    forall a. Int -> [a] -> ([a], [a])
    splitAt Int
    diff Forest a
    forest
              advance :: Int
    advance = Forest a -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length Forest a
    dropped
              ti' :: ForestStoreIter
    ti' = ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
    setBitSlice ForestStoreIter
    ti Int
    pos Int
    d (Word32
    curIdxWord32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    +Int -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    advance)
            in
            if Int
    advanceInt -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Int
    diff then Int
    -> Depth
    -> [(ForestStoreIter, Forest a)]
    -> [(ForestStoreIter, Forest a)]
    forall a. Int -> Depth -> Cache a -> Cache a
    moveToChild (Int
    posInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    d) Depth
    ds ((ForestStoreIter
    ti',Forest a
    remain)(ForestStoreIter, Forest a)
    -> [(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)]
    forall a. a -> [a] -> [a]
    :[(ForestStoreIter, Forest a)]
    parents)
            else (ForestStoreIter
    ti',Forest a
    remain)(ForestStoreIter, Forest a)
    -> [(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)]
    forall a. a -> [a] -> [a]
    :[(ForestStoreIter, Forest a)]
    parents -- node not found
        in Int
    -> Int
    -> [(ForestStoreIter, Forest a)]
    -> [(ForestStoreIter, Forest a)]
    moveWithinLevel Int
    pos Int
    d ([(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)])
    -> [(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)]
    forall a b. (a -> b) -> a -> b
    $ case Depth
    ds of
            [] -> [(ForestStoreIter, Forest a)]
    cache
            (Int
    d':Depth
    _) -> ((ForestStoreIter, Forest a) -> Bool)
    -> [(ForestStoreIter, Forest a)] -> [(ForestStoreIter, Forest a)]
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile (Int -> Int -> (ForestStoreIter, Forest a) -> Bool
    forall {b}. Int -> Int -> (ForestStoreIter, b) -> Bool
    isNonZero (Int
    posInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    d) Int
    d') [(ForestStoreIter, Forest a)]
    cache

      -- Descend into the topmost forest to find the goal iterator. The position
      -- and the remainding depths specify the index in the cache that is zero.
      -- All indices in front of pos coincide with that of the goal iterator.
      moveToChild :: Int -> Depth -> Cache a -> Cache a
      moveToChild :: forall a. Int -> Depth -> Cache a -> Cache a
    moveToChild Int
    pos [] Cache a
    cache = Cache a
    cache -- we can't set more than the leaf
      moveToChild Int
    pos (Int
    d:Depth
    ds) cache :: Cache a
    cache@((ForestStoreIter
    ti,Forest a
    forest):Cache a
    parents)
        | ForestStoreIter -> Int -> Int -> Word32
    getBitSlice ForestStoreIter
    goal Int
    pos Int
    d Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word32
    0 = Cache a
    cache
        | Bool
    otherwise = case Forest a
    forest of
          [] -> Cache a
    cache -- impossible request
          Node { subForest :: forall a. Tree a -> [Tree a]
    subForest = Forest a
    children }:Forest a
    _ ->
            let
              childIdx :: Int
              childIdx :: Int
    childIdx = Word32 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (ForestStoreIter -> Int -> Int -> Word32
    getBitSlice ForestStoreIter
    goal Int
    pos Int
    d)Int -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1
              (Forest a
    dropped, Forest a
    remain) = Int -> Forest a -> (Forest a, Forest a)
    forall a. Int -> [a] -> ([a], [a])
    splitAt Int
    childIdx Forest a
    children
              advanced :: Int
    advanced = Forest a -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length Forest a
    dropped
              ti' :: ForestStoreIter
    ti' = ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
    setBitSlice ForestStoreIter
    ti Int
    pos Int
    d (Int -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    advancedWord32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    +Word32
    1)
            in if Int
    advancedInt -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <Int
    childIdx then ((ForestStoreIter
    ti',Forest a
    remain)(ForestStoreIter, Forest a) -> Cache a -> Cache a
    forall a. a -> [a] -> [a]
    :Cache a
    cache) else
               Int -> Depth -> Cache a -> Cache a
    forall a. Int -> Depth -> Cache a -> Cache a
    moveToChild (Int
    posInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    d) Depth
    ds ((ForestStoreIter
    ti',Forest a
    remain)(ForestStoreIter, Forest a) -> Cache a -> Cache a
    forall a. a -> [a] -> [a]
    :Cache a
    cache)

    -- | Advance to the given iterator and return weather this was successful.
    --
    checkSuccess :: Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    checkSuccess :: forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    checkSuccess Depth
    depth ForestStoreIter
    iter Cache a
    cache = case Depth -> ForestStoreIter -> Cache a -> Cache a
    forall a. Depth -> ForestStoreIter -> Cache a -> Cache a
    advanceCache Depth
    depth ForestStoreIter
    iter Cache a
    cache of
        cache' :: Cache a
    cache'@((ForestStoreIter
    cur,Forest a
    sibs):Cache a
    _) -> (ForestStoreIter -> ForestStoreIter -> Bool
    cmp ForestStoreIter
    cur ForestStoreIter
    iter Bool -> Bool -> Bool
    && Bool -> Bool
    not (Forest a -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null Forest a
    sibs), Cache a
    cache')
        [] -> (Bool
    False, [])
      where
      cmp :: ForestStoreIter -> ForestStoreIter -> Bool
    cmp (ForestStoreIter Int32
    _ Word32
    a1 Word32
    b1 Word32
    c1) (ForestStoreIter Int32
    _ Word32
    a2 Word32
    b2 Word32
    c2) =
          Word32
    a1Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Word32
    a2 Bool -> Bool -> Bool
    && Word32
    b1Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Word32
    b2 Bool -> Bool -> Bool
    && Word32
    c2Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Word32
    c2

    -- | Get the leaf index of this iterator.
    --
    -- * Due to the way we construct the 'TreeIter's, we can check which the last
    --   level of an iterator is: The bit sequence of level n is zero if n is
    --   greater or equal to the level that the iterator refers to. The returned
    --   triple is (pos, leaf, zero) such that pos..pos+leaf denotes the leaf
    --   index and pos+leaf..pos+leaf+zero denotes the bit field that is zero.
    --
    getTreeIterLeaf :: Depth -> ForestStoreIter -> (Int, Int, Int)
    getTreeIterLeaf :: Depth -> ForestStoreIter -> (Int, Int, Int)
    getTreeIterLeaf Depth
    ds ForestStoreIter
    ti = Int -> Int -> Depth -> (Int, Int, Int)
    gTIL Int
    0 Int
    0 Depth
    ds
      where
      gTIL :: Int -> Int -> Depth -> (Int, Int, Int)
    gTIL Int
    pos Int
    dCur (Int
    dNext:Depth
    ds)
        | ForestStoreIter -> Int -> Int -> Word32
    getBitSlice ForestStoreIter
    ti (Int
    posInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    dCur) Int
    dNextWord32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Word32
    0 = (Int
    pos,Int
    dCur,Int
    dNext)
        | Bool
    otherwise = Int -> Int -> Depth -> (Int, Int, Int)
    gTIL (Int
    posInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    dCur) Int
    dNext Depth
    ds
      gTIL Int
    pos Int
    d [] = (Int
    pos, Int
    d, Int
    0)

    -- | Move an iterator forwards on the same level.
    --
    iterNext :: Depth -> ForestStoreIter -> Cache a -> (Maybe ForestStoreIter, Cache a)
    iterNext :: forall a.
    Depth
    -> ForestStoreIter -> Cache a -> (Maybe ForestStoreIter, Cache a)
    iterNext Depth
    depth ForestStoreIter
    iter Cache a
    cache = let
        (Int
    pos,Int
    leaf,Int
    _child) = Depth -> ForestStoreIter -> (Int, Int, Int)
    getTreeIterLeaf Depth
    depth ForestStoreIter
    iter
        curIdx :: Word32
    curIdx = ForestStoreIter -> Int -> Int -> Word32
    getBitSlice ForestStoreIter
    iter Int
    pos Int
    leaf
        nextIdx :: Word32
    nextIdx = Word32
    curIdxWord32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    +Word32
    1
        nextIter :: ForestStoreIter
    nextIter = ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
    setBitSlice ForestStoreIter
    iter Int
    pos Int
    leaf Word32
    nextIdx
      in
      if Word32
    nextIdxWord32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Int -> Word32
    forall a. Bits a => Int -> a
    bit Int
    leaf then (Maybe ForestStoreIter
    forall a. Maybe a
    Nothing, Cache a
    cache) else
      case Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    checkSuccess Depth
    depth ForestStoreIter
    nextIter Cache a
    cache of
        (Bool
    True, Cache a
    cache) -> (ForestStoreIter -> Maybe ForestStoreIter
    forall a. a -> Maybe a
    Just ForestStoreIter
    nextIter, Cache a
    cache)
        (Bool
    False, Cache a
    cache) -> (Maybe ForestStoreIter
    forall a. Maybe a
    Nothing, Cache a
    cache)

    -- | Move down to the child of the given iterator.
    --
    iterNthChild :: Depth -> Int -> ForestStoreIter -> Cache a  ->
                    (Maybe ForestStoreIter, Cache a)
    iterNthChild :: forall a.
    Depth
    -> Int
    -> ForestStoreIter
    -> Cache a
    -> (Maybe ForestStoreIter, Cache a)
    iterNthChild Depth
    depth Int
    childIdx_ ForestStoreIter
    iter Cache a
    cache = let
        (Int
    pos,Int
    leaf,Int
    child) = Depth -> ForestStoreIter -> (Int, Int, Int)
    getTreeIterLeaf Depth
    depth ForestStoreIter
    iter
        childIdx :: Word32
    childIdx = Int -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    childIdx_Word32 -> Word32 -> Word32
    forall a. Num a => a -> a -> a
    +Word32
    1
        nextIter :: ForestStoreIter
    nextIter = ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
    setBitSlice ForestStoreIter
    iter (Int
    posInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    leaf) Int
    child Word32
    childIdx
      in
      if Word32
    childIdxWord32 -> Word32 -> Bool
    forall a. Ord a => a -> a -> Bool
    >=Int -> Word32
    forall a. Bits a => Int -> a
    bit Int
    child then (Maybe ForestStoreIter
    forall a. Maybe a
    Nothing, Cache a
    cache) else
      case Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    checkSuccess Depth
    depth ForestStoreIter
    nextIter Cache a
    cache of
        (Bool
    True, Cache a
    cache) -> (ForestStoreIter -> Maybe ForestStoreIter
    forall a. a -> Maybe a
    Just ForestStoreIter
    nextIter, Cache a
    cache)
        (Bool
    False, Cache a
    cache) -> (Maybe ForestStoreIter
    forall a. Maybe a
    Nothing, Cache a
    cache)

    -- | Descend to the first child.
    --
    iterNChildren :: Depth -> ForestStoreIter -> Cache a -> (Int, Cache a)
    iterNChildren :: forall a. Depth -> ForestStoreIter -> Cache a -> (Int, Cache a)
    iterNChildren Depth
    depth ForestStoreIter
    iter Cache a
    cache = case Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    checkSuccess Depth
    depth ForestStoreIter
    iter Cache a
    cache of
      (Bool
    True, cache :: Cache a
    cache@((ForestStoreIter
    _,Node { subForest :: forall a. Tree a -> [Tree a]
    subForest = Forest a
    forest}:Forest a
    _):Cache a
    _)) -> (Forest a -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length Forest a
    forest, Cache a
    cache)
      (Bool
    _, Cache a
    cache) -> (Int
    0, Cache a
    cache)

    -- | Ascend to parent.
    --
    iterParent :: Depth -> ForestStoreIter -> Maybe ForestStoreIter
    iterParent :: Depth -> ForestStoreIter -> Maybe ForestStoreIter
    iterParent Depth
    depth ForestStoreIter
    iter = let
        (Int
    pos,Int
    leaf,Int
    _child) = Depth -> ForestStoreIter -> (Int, Int, Int)
    getTreeIterLeaf Depth
    depth ForestStoreIter
    iter
      in if Int
    posInt -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Int
    0 then Maybe ForestStoreIter
    forall a. Maybe a
    Nothing else
         if ForestStoreIter -> Int -> Int -> Word32
    getBitSlice ForestStoreIter
    iter Int
    pos Int
    leafWord32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    ==Word32
    0 then Maybe ForestStoreIter
    forall a. Maybe a
    Nothing else
         ForestStoreIter -> Maybe ForestStoreIter
    forall a. a -> Maybe a
    Just (ForestStoreIter -> Int -> Int -> Word32 -> ForestStoreIter
    setBitSlice ForestStoreIter
    iter Int
    pos Int
    leaf Word32
    0)

    -- | Insert nodes into the store.
    --
    -- * The given list of nodes is inserted into given parent at @pos@.
    --   If the parent existed, the function returns @Just path@ where @path@
    --   is the position of the newly inserted elements. If @pos@ is negative
    --   or greater or equal to the number of children of the node at @path@,
    --   the new nodes are appended to the list.
    --
    forestStoreInsertForest :: MonadIO m
     => ForestStore a -- ^ the store
     -> TreePath    -- ^ @path@ - the position of the parent
     -> Int         -- ^ @pos@ - the index of the new tree
     -> Forest a    -- ^ the list of trees to be inserted
     -> m ()
    forestStoreInsertForest :: forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> Int -> Forest a -> m ()
    forestStoreInsertForest (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model) TreePath
    path Int
    pos Forest a
    nodes = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ do
      ipath <- TreePath -> IO [Int32]
    forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
    treePathGetIndices' TreePath
    path
      customStoreInvalidateIters $ CustomStore model
      (idx, toggle) <- atomicModifyIORef (customStoreGetPrivate $ CustomStore model) $
        \store :: Store a
    store@Store { depth :: forall a. Store a -> Depth
    depth = Depth
    d, content :: forall a. Store a -> Cache a
    content = Cache a
    cache } ->
        case Forest a
    -> Forest a -> [Int32] -> Int -> Maybe (Forest a, Int, Bool)
    forall a.
    Forest a
    -> Forest a -> [Int32] -> Int -> Maybe (Forest a, Int, Bool)
    insertIntoForest (Cache a -> Forest a
    forall a. Cache a -> Forest a
    cacheToStore Cache a
    cache) Forest a
    nodes [Int32]
    ipath Int
    pos of
          Maybe (Forest a, Int, Bool)
    Nothing -> [Char] -> (Store a, (Int, Bool))
    forall a. (?callStack::CallStack) => [Char] -> a
    error ([Char]
    "forestStoreInsertForest: path does not exist " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Int32] -> [Char]
    forall a. Show a => a -> [Char]
    show [Int32]
    ipath)
          Just (Forest a
    newForest, Int
    idx, Bool
    toggle) ->
           let depth :: Depth
    depth = Forest a -> Depth
    forall a. Forest a -> Depth
    calcForestDepth Forest a
    newForest
            in (Store { depth :: Depth
    depth = Depth
    depth,
                        content :: Cache a
    content = Forest a -> Cache a
    forall a. Forest a -> Cache a
    storeToCache Forest a
    newForest },
               (Int
    idx, Bool
    toggle))
      Store { depth = depth } <- readIORef (customStoreGetPrivate $ CustomStore model)
      let rpath = [Int32] -> [Int32]
    forall a. [a] -> [a]
    reverse [Int32]
    ipath
      stamp <- customStoreGetStamp $ CustomStore model
      sequence_ [ let p' = [Int32] -> [Int32]
    forall a. [a] -> [a]
    reverse [Int32]
    p
                      Just iter = fromPath depth p'
                   in do
                      p'' <- treePathNewFromIndices' p'
                      treeModelRowInserted (CustomStore model) p'' =<< fromForestStoreIter (forestStoreIterSetStamp iter stamp)
                | (i, node) <- zip [idx..] nodes
                , p <- paths (fromIntegral i : rpath) node ]
      let Just iter = fromPath depth ipath
      when toggle $ treeModelRowHasChildToggled (CustomStore model) path
                    =<< fromForestStoreIter (forestStoreIterSetStamp iter stamp)

      where paths :: [Int32] -> Tree a -> [[Int32]]
            paths :: forall a. [Int32] -> Tree a -> [[Int32]]
    paths [Int32]
    path Node { subForest :: forall a. Tree a -> [Tree a]
    subForest = [Tree a]
    ts } =
              [Int32]
    path [Int32] -> [[Int32]] -> [[Int32]]
    forall a. a -> [a] -> [a]
    : [[[Int32]]] -> [[Int32]]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat [ [Int32] -> Tree a -> [[Int32]]
    forall a. [Int32] -> Tree a -> [[Int32]]
    paths (Int32
    nInt32 -> [Int32] -> [Int32]
    forall a. a -> [a] -> [a]
    :[Int32]
    path) Tree a
    t | (Int32
    n, Tree a
    t) <- [Int32] -> [Tree a] -> [(Int32, Tree a)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Int32
    0..] [Tree a]
    ts ]

    -- | Insert a node into the store.
    --
    forestStoreInsertTree :: MonadIO m
     => ForestStore a -- ^ the store
     -> TreePath    -- ^ @path@ - the position of the parent
     -> Int         -- ^ @pos@ - the index of the new tree
     -> Tree a      -- ^ the value to be inserted
     -> m ()
    forestStoreInsertTree :: forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> Int -> Tree a -> m ()
    forestStoreInsertTree ForestStore a
    store TreePath
    path Int
    pos Tree a
    node =
      ForestStore a -> TreePath -> Int -> Forest a -> m ()
    forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> Int -> Forest a -> m ()
    forestStoreInsertForest ForestStore a
    store TreePath
    path Int
    pos [Tree a
    node]

    -- | Insert a single node into the store.
    --
    -- * This function inserts a single node without children into the tree.
    --   Its arguments are similar to those of 'forestStoreInsert'.
    --
    forestStoreInsert :: MonadIO m
     => ForestStore a -- ^ the store
     -> TreePath    -- ^ @path@ - the position of the parent
     -> Int         -- ^ @pos@ - the index of the new tree
     -> a           -- ^ the value to be inserted
     -> m ()
    forestStoreInsert :: forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> Int -> a -> m ()
    forestStoreInsert ForestStore a
    store TreePath
    path Int
    pos a
    node =
      ForestStore a -> TreePath -> Int -> Forest a -> m ()
    forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> Int -> Forest a -> m ()
    forestStoreInsertForest ForestStore a
    store TreePath
    path Int
    pos [a -> Forest a -> Tree a
    forall a. a -> [Tree a] -> Tree a
    Node a
    node []]

    -- | Insert nodes into a forest.
    --
    -- * If the parent was found, returns the new tree, the child number
    --   and a flag denoting if these new nodes were the first children
    --   of the parent.
    --
    insertIntoForest :: Forest a -> Forest a -> [Int32] -> Int ->
                        Maybe (Forest a, Int, Bool)
    insertIntoForest :: forall a.
    Forest a
    -> Forest a -> [Int32] -> Int -> Maybe (Forest a, Int, Bool)
    insertIntoForest Forest a
    forest Forest a
    nodes [] Int
    pos
      | Int
    posInt -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <Int
    0 = (Forest a, Int, Bool) -> Maybe (Forest a, Int, Bool)
    forall a. a -> Maybe a
    Just (Forest a
    forestForest a -> Forest a -> Forest a
    forall a. [a] -> [a] -> [a]
    ++Forest a
    nodes, Forest a -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length Forest a
    forest, Forest a -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null Forest a
    forest)
      | Bool
    otherwise = (Forest a, Int, Bool) -> Maybe (Forest a, Int, Bool)
    forall a. a -> Maybe a
    Just (Forest a
    prevForest a -> Forest a -> Forest a
    forall a. [a] -> [a] -> [a]
    ++Forest a
    nodesForest a -> Forest a -> Forest a
    forall a. [a] -> [a] -> [a]
    ++Forest a
    next, Forest a -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length Forest a
    prev, Forest a -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null Forest a
    forest)
        where (Forest a
    prev, Forest a
    next) = Int -> Forest a -> (Forest a, Forest a)
    forall a. Int -> [a] -> ([a], [a])
    splitAt Int
    pos Forest a
    forest
    insertIntoForest Forest a
    forest Forest a
    nodes (Int32
    p:[Int32]
    ps) Int
    pos = case Int -> Forest a -> (Forest a, Forest a)
    forall a. Int -> [a] -> ([a], [a])
    splitAt (Int32 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int32
    p) Forest a
    forest of
      (Forest a
    prev, []) -> Maybe (Forest a, Int, Bool)
    forall a. Maybe a
    Nothing
      (Forest a
    prev, Node { rootLabel :: forall a. Tree a -> a
    rootLabel = a
    val,
                    subForest :: forall a. Tree a -> [Tree a]
    subForest = Forest a
    for}:Forest a
    next) ->
        case Forest a
    -> Forest a -> [Int32] -> Int -> Maybe (Forest a, Int, Bool)
    forall a.
    Forest a
    -> Forest a -> [Int32] -> Int -> Maybe (Forest a, Int, Bool)
    insertIntoForest Forest a
    for Forest a
    nodes [Int32]
    ps Int
    pos of
          Maybe (Forest a, Int, Bool)
    Nothing -> Maybe (Forest a, Int, Bool)
    forall a. Maybe a
    Nothing
          Just (Forest a
    for, Int
    pos, Bool
    toggle) -> (Forest a, Int, Bool) -> Maybe (Forest a, Int, Bool)
    forall a. a -> Maybe a
    Just (Forest a
    prevForest a -> Forest a -> Forest a
    forall a. [a] -> [a] -> [a]
    ++Node { rootLabel :: a
    rootLabel = a
    val,
                                                        subForest :: Forest a
    subForest = Forest a
    for }Tree a -> Forest a -> Forest a
    forall a. a -> [a] -> [a]
    :Forest a
    next,
                                           Int
    pos, Bool
    toggle)

    -- | Remove a node from the store.
    --
    -- * The node denoted by the path is removed, along with all its children.
    --   The function returns @True@ if the given node was found.
    --
    forestStoreRemove :: MonadIO m => ForestStore a -> TreePath -> m Bool
    forestStoreRemove :: forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> m Bool
    forestStoreRemove ForestStore a
    model TreePath
    path = TreePath -> m [Int32]
    forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
    treePathGetIndices' TreePath
    path m [Int32] -> ([Int32] -> m Bool) -> m Bool
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= ForestStore a -> TreePath -> [Int32] -> m Bool
    forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> [Int32] -> m Bool
    forestStoreRemoveImpl ForestStore a
    model TreePath
    path

    forestStoreRemoveImpl :: MonadIO m => ForestStore a -> TreePath -> [Int32] -> m Bool
      --TODO: eliminate this special case without segfaulting!
    forestStoreRemoveImpl :: forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> [Int32] -> m Bool
    forestStoreRemoveImpl (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model) TreePath
    _ [] = Bool -> m Bool
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False
    forestStoreRemoveImpl (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model) TreePath
    path [Int32]
    ipath = IO Bool -> m Bool
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO Bool -> m Bool) -> IO Bool -> m Bool
    forall a b. (a -> b) -> a -> b
    $ do
      CustomStore (IORef (Store a)) a -> IO ()
    forall (m :: * -> *) private row.
    MonadIO m =>
    CustomStore private row -> m ()
    customStoreInvalidateIters (ManagedPtr (CustomStore (IORef (Store a)) a)
    -> CustomStore (IORef (Store a)) a
    forall private row.
    ManagedPtr (CustomStore private row) -> CustomStore private row
    CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model)
      (found, toggle) <- IORef (Store a)
    -> (Store a -> (Store a, (Bool, Bool))) -> IO (Bool, Bool)
    forall a b. IORef a -> (a -> (a, b)) -> IO b
    atomicModifyIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
    forall private row. CustomStore private row -> private
    customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
    -> CustomStore (IORef (Store a)) a
    forall private row.
    ManagedPtr (CustomStore private row) -> CustomStore private row
    CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model)) ((Store a -> (Store a, (Bool, Bool))) -> IO (Bool, Bool))
    -> (Store a -> (Store a, (Bool, Bool))) -> IO (Bool, Bool)
    forall a b. (a -> b) -> a -> b
    $
        \store :: Store a
    store@Store { depth :: forall a. Store a -> Depth
    depth = Depth
    d, content :: forall a. Store a -> Cache a
    content = Cache a
    cache } ->
        if Cache a -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null Cache a
    cache then (Store a
    store, (Bool
    False, Bool
    False)) else
        case Forest a -> [Int32] -> Maybe (Forest a, Bool)
    forall a. Forest a -> [Int32] -> Maybe (Forest a, Bool)
    deleteFromForest (Cache a -> Forest a
    forall a. Cache a -> Forest a
    cacheToStore Cache a
    cache) [Int32]
    ipath of
          Maybe (Forest a, Bool)
    Nothing -> (Store a
    store, (Bool
    False, Bool
    False))
          Just (Forest a
    newForest, Bool
    toggle) ->
            (Store { depth :: Depth
    depth = Depth
    d, -- this might be a space leak
                     content :: Cache a
    content = Forest a -> Cache a
    forall a. Forest a -> Cache a
    storeToCache Forest a
    newForest }, (Bool
    True, Bool
    toggle))
      when found $ do
        when (toggle && not (null ipath)) $ do
          Store { depth = depth } <- readIORef (customStoreGetPrivate (CustomStore model))
          let iparent = [Int32] -> [Int32]
    forall a. (?callStack::CallStack) => [a] -> [a]
    init [Int32]
    ipath
              Just iter = fromPath depth iparent
          parent <- treePathNewFromIndices' iparent
          treeModelRowHasChildToggled (CustomStore model) parent =<< fromForestStoreIter iter
        treeModelRowDeleted (CustomStore model) path
      return found

    forestStoreClear :: MonadIO m => ForestStore a -> m ()
    forestStoreClear :: forall (m :: * -> *) a. MonadIO m => ForestStore a -> m ()
    forestStoreClear (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model) = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ do
      CustomStore (IORef (Store a)) a -> IO ()
    forall (m :: * -> *) private row.
    MonadIO m =>
    CustomStore private row -> m ()
    customStoreInvalidateIters (ManagedPtr (CustomStore (IORef (Store a)) a)
    -> CustomStore (IORef (Store a)) a
    forall private row.
    ManagedPtr (CustomStore private row) -> CustomStore private row
    CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model)
      Store { content = cache } <- IORef (Store a) -> IO (Store a)
    forall a. IORef a -> IO a
    readIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
    forall private row. CustomStore private row -> private
    customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
    -> CustomStore (IORef (Store a)) a
    forall private row.
    ManagedPtr (CustomStore private row) -> CustomStore private row
    CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model))
      let forest = Cache a -> Forest a
    forall a. Cache a -> Forest a
    cacheToStore Cache a
    cache
      writeIORef (customStoreGetPrivate (CustomStore model)) Store {
          depth = calcForestDepth [],
          content = storeToCache []
        }
      let loop (-1) = () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          loop   Int
    n  = [Int32] -> IO TreePath
    forall (m :: * -> *). MonadIO m => [Int32] -> m TreePath
    treePathNewFromIndices' [Int -> Int32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n] IO TreePath -> (TreePath -> IO ()) -> IO ()
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= CustomStore (IORef (Store a)) a -> TreePath -> IO ()
    forall (m :: * -> *) a.
    (?callStack::CallStack, MonadIO m, IsTreeModel a) =>
    a -> TreePath -> m ()
    treeModelRowDeleted (ManagedPtr (CustomStore (IORef (Store a)) a)
    -> CustomStore (IORef (Store a)) a
    forall private row.
    ManagedPtr (CustomStore private row) -> CustomStore private row
    CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model) IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Int -> IO ()
    loop (Int
    nInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1)
      loop (length forest - 1)

    -- | Remove a node from a rose tree.
    --
    -- * Returns the new tree if the node was found. The returned flag is
    --   @True@ if deleting the node left the parent without any children.
    --
    deleteFromForest :: Forest a -> [Int32] -> Maybe (Forest a, Bool)
    deleteFromForest :: forall a. Forest a -> [Int32] -> Maybe (Forest a, Bool)
    deleteFromForest Forest a
    forest [] = (Forest a, Bool) -> Maybe (Forest a, Bool)
    forall a. a -> Maybe a
    Just ([], Bool
    False)
    deleteFromForest Forest a
    forest (Int32
    p:[Int32]
    ps) =
      case Int -> Forest a -> (Forest a, Forest a)
    forall a. Int -> [a] -> ([a], [a])
    splitAt (Int32 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int32
    p) Forest a
    forest of
        (Forest a
    prev, kill :: Tree a
    kill@Node { rootLabel :: forall a. Tree a -> a
    rootLabel = a
    val,
                           subForest :: forall a. Tree a -> [Tree a]
    subForest = Forest a
    for}:Forest a
    next) ->
          if [Int32] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Int32]
    ps then (Forest a, Bool) -> Maybe (Forest a, Bool)
    forall a. a -> Maybe a
    Just (Forest a
    prevForest a -> Forest a -> Forest a
    forall a. [a] -> [a] -> [a]
    ++Forest a
    next, Forest a -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null Forest a
    prev Bool -> Bool -> Bool
    && Forest a -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null Forest a
    next) else
          case Forest a -> [Int32] -> Maybe (Forest a, Bool)
    forall a. Forest a -> [Int32] -> Maybe (Forest a, Bool)
    deleteFromForest Forest a
    for [Int32]
    ps of
            Maybe (Forest a, Bool)
    Nothing -> Maybe (Forest a, Bool)
    forall a. Maybe a
    Nothing
            Just (Forest a
    for,Bool
    toggle) -> (Forest a, Bool) -> Maybe (Forest a, Bool)
    forall a. a -> Maybe a
    Just (Forest a
    prevForest a -> Forest a -> Forest a
    forall a. [a] -> [a] -> [a]
    ++Node {rootLabel :: a
    rootLabel = a
    val,
                                                   subForest :: Forest a
    subForest = Forest a
    for }Tree a -> Forest a -> Forest a
    forall a. a -> [a] -> [a]
    :Forest a
    next, Bool
    toggle)
        (Forest a
    prev, []) -> Maybe (Forest a, Bool)
    forall a. Maybe a
    Nothing

    -- | Set a node in the store.
    --
    forestStoreSetValue :: MonadIO m => ForestStore a -> TreePath -> a -> m ()
    forestStoreSetValue :: forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> a -> m ()
    forestStoreSetValue ForestStore a
    store TreePath
    path a
    value = ForestStore a -> TreePath -> (a -> m a) -> m Bool
    forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> (a -> m a) -> m Bool
    forestStoreChangeM ForestStore a
    store TreePath
    path (\a
    _ -> a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a
    value)
                                      m Bool -> m () -> m ()
    forall a b. m a -> m b -> m b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> () -> m ()
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- | Change a node in the store.
    --
    -- * Returns @True@ if the node was found. For a monadic version, see
    --   'forestStoreChangeM'.
    --
    forestStoreChange :: MonadIO m => ForestStore a -> TreePath -> (a -> a) -> m Bool
    forestStoreChange :: forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> (a -> a) -> m Bool
    forestStoreChange ForestStore a
    store TreePath
    path a -> a
    func = ForestStore a -> TreePath -> (a -> m a) -> m Bool
    forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> (a -> m a) -> m Bool
    forestStoreChangeM ForestStore a
    store TreePath
    path (a -> m a
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a -> m a) -> (a -> a) -> a -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> a
    func)

    -- | Change a node in the store.
    --
    -- * Returns @True@ if the node was found. For a purely functional version, see
    --   'forestStoreChange'.
    --
    forestStoreChangeM :: MonadIO m => ForestStore a -> TreePath -> (a -> m a) -> m Bool
    forestStoreChangeM :: forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> (a -> m a) -> m Bool
    forestStoreChangeM (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model) TreePath
    path a -> m a
    act = do
      ipath <- TreePath -> m [Int32]
    forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
    treePathGetIndices' TreePath
    path
      customStoreInvalidateIters (CustomStore model)
      store@Store { depth = d, content = cache } <-
          liftIO $ readIORef (customStoreGetPrivate (CustomStore model))
      (store'@Store { depth = d, content = cache }, found) <- do
        mRes <- changeForest (cacheToStore cache) act ipath
        return $ case mRes of
          Maybe (Forest a)
    Nothing -> (Store a
    store, Bool
    False)
          Just Forest a
    newForest -> (Store { depth :: Depth
    depth = Depth
    d,
                                     content :: Cache a
    content = Forest a -> Cache a
    forall a. Forest a -> Cache a
    storeToCache Forest a
    newForest }, Bool
    True)
      liftIO $ writeIORef (customStoreGetPrivate (CustomStore model)) store'
      let Just iter = fromPath d ipath
      stamp <- customStoreGetStamp (CustomStore model)
      when found $ treeModelRowChanged (CustomStore model) path =<< fromForestStoreIter (forestStoreIterSetStamp iter stamp)
      return found

    -- | Change a node in the forest.
    --
    -- * Returns @True@ if the given node was found.
    --
    changeForest :: MonadIO m => Forest a -> (a -> m a) -> [Int32] -> m (Maybe (Forest a))
    changeForest :: forall (m :: * -> *) a.
    MonadIO m =>
    Forest a -> (a -> m a) -> [Int32] -> m (Maybe (Forest a))
    changeForest Forest a
    forest a -> m a
    act [] = Maybe (Forest a) -> m (Maybe (Forest a))
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Forest a)
    forall a. Maybe a
    Nothing
    changeForest Forest a
    forest a -> m a
    act (Int32
    p:[Int32]
    ps) = case Int -> Forest a -> (Forest a, Forest a)
    forall a. Int -> [a] -> ([a], [a])
    splitAt (Int32 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int32
    p) Forest a
    forest of
      (Forest a
    prev, []) -> Maybe (Forest a) -> m (Maybe (Forest a))
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Forest a)
    forall a. Maybe a
    Nothing
      (Forest a
    prev, Node { rootLabel :: forall a. Tree a -> a
    rootLabel = a
    val,
                    subForest :: forall a. Tree a -> [Tree a]
    subForest = Forest a
    for}:Forest a
    next) ->
        if [Int32] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Int32]
    ps then do
          val' <- a -> m a
    act a
    val
          return (Just (prev++Node { rootLabel = val',
                                     subForest = for }:next))
        else do
          mFor <- Forest a -> (a -> m a) -> [Int32] -> m (Maybe (Forest a))
    forall (m :: * -> *) a.
    MonadIO m =>
    Forest a -> (a -> m a) -> [Int32] -> m (Maybe (Forest a))
    changeForest Forest a
    for a -> m a
    act [Int32]
    ps
          case mFor of
            Maybe (Forest a)
    Nothing -> Maybe (Forest a) -> m (Maybe (Forest a))
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Forest a)
    forall a. Maybe a
    Nothing
            Just Forest a
    for -> Maybe (Forest a) -> m (Maybe (Forest a))
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (Forest a) -> m (Maybe (Forest a)))
    -> Maybe (Forest a) -> m (Maybe (Forest a))
    forall a b. (a -> b) -> a -> b
    $ Forest a -> Maybe (Forest a)
    forall a. a -> Maybe a
    Just (Forest a
    prevForest a -> Forest a -> Forest a
    forall a. [a] -> [a] -> [a]
    ++Node { rootLabel :: a
    rootLabel = a
    val,
                                                    subForest :: Forest a
    subForest = Forest a
    for }Tree a -> Forest a -> Forest a
    forall a. a -> [a] -> [a]
    :Forest a
    next)

    -- | Extract one node from the current model. Fails if the given
    --   'TreePath' refers to a non-existent node.
    --
    forestStoreGetValue :: (Applicative m, MonadIO m) => ForestStore a -> TreePath -> m a
    forestStoreGetValue :: forall (m :: * -> *) a.
    (Applicative m, MonadIO m) =>
    ForestStore a -> TreePath -> m a
    forestStoreGetValue ForestStore a
    model TreePath
    path = Tree a -> a
    forall a. Tree a -> a
    rootLabel (Tree a -> a) -> m (Tree a) -> m a
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ForestStore a -> TreePath -> m (Tree a)
    forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> m (Tree a)
    forestStoreGetTree ForestStore a
    model TreePath
    path

    -- | Extract a subtree from the current model. Fails if the given
    --   'TreePath' refers to a non-existent node.
    --
    forestStoreGetTree :: MonadIO m => ForestStore a -> TreePath -> m (Tree a)
    forestStoreGetTree :: forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> m (Tree a)
    forestStoreGetTree (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model) TreePath
    path = IO (Tree a) -> m (Tree a)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (Tree a) -> m (Tree a)) -> IO (Tree a) -> m (Tree a)
    forall a b. (a -> b) -> a -> b
    $ do
      ipath <- TreePath -> IO [Int32]
    forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
    treePathGetIndices' TreePath
    path
      store@Store { depth = d, content = cache } <-
          readIORef (customStoreGetPrivate (CustomStore model))
      case fromPath d ipath of
        (Just ForestStoreIter
    iter) -> do
          let (Bool
    res, Cache a
    cache') = Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    checkSuccess Depth
    d ForestStoreIter
    iter Cache a
    cache
          IORef (Store a) -> Store a -> IO ()
    forall a. IORef a -> a -> IO ()
    writeIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
    forall private row. CustomStore private row -> private
    customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
    -> CustomStore (IORef (Store a)) a
    forall private row.
    ManagedPtr (CustomStore private row) -> CustomStore private row
    CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model)) Store a
    store { content = cache' }
          case Cache a
    cache' of
            ((ForestStoreIter
    _,Tree a
    node:Forest a
    _):Cache a
    _) | Bool
    res -> Tree a -> IO (Tree a)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Tree a
    node
            Cache a
    _ -> [Char] -> IO (Tree a)
    forall a. [Char] -> IO a
    forall (m :: * -> *) a. MonadFail m => [Char] -> m a
    fail ([Char]
    "forestStoreGetTree: path does not exist " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Int32] -> [Char]
    forall a. Show a => a -> [Char]
    show [Int32]
    ipath)
        Maybe ForestStoreIter
    _ -> [Char] -> IO (Tree a)
    forall a. [Char] -> IO a
    forall (m :: * -> *) a. MonadFail m => [Char] -> m a
    fail ([Char]
    "forestStoreGetTree: path does not exist " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Int32] -> [Char]
    forall a. Show a => a -> [Char]
    show [Int32]
    ipath)

    -- | Extract the forest from the current model.
    --
    forestStoreGetForest :: MonadIO m => ForestStore a -> m (Forest a)
    forestStoreGetForest :: forall (m :: * -> *) a. MonadIO m => ForestStore a -> m (Forest a)
    forestStoreGetForest (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model) = IO (Forest a) -> m (Forest a)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (Forest a) -> m (Forest a)) -> IO (Forest a) -> m (Forest a)
    forall a b. (a -> b) -> a -> b
    $ do
      store@Store { depth = d, content = cache } <-
          IORef (Store a) -> IO (Store a)
    forall a. IORef a -> IO a
    readIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
    forall private row. CustomStore private row -> private
    customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
    -> CustomStore (IORef (Store a)) a
    forall private row.
    ManagedPtr (CustomStore private row) -> CustomStore private row
    CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model))
      return $ cacheToStore cache

    -- | Extract a subtree from the current model. Like 'forestStoreGetTree'
    --   but returns @Nothing@ if the path refers to a non-existant node.
    --
    forestStoreLookup :: MonadIO m => ForestStore a -> TreePath -> m (Maybe (Tree a))
    forestStoreLookup :: forall (m :: * -> *) a.
    MonadIO m =>
    ForestStore a -> TreePath -> m (Maybe (Tree a))
    forestStoreLookup (ForestStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model) TreePath
    path = IO (Maybe (Tree a)) -> m (Maybe (Tree a))
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (Maybe (Tree a)) -> m (Maybe (Tree a)))
    -> IO (Maybe (Tree a)) -> m (Maybe (Tree a))
    forall a b. (a -> b) -> a -> b
    $ do
      ipath <- TreePath -> IO [Int32]
    forall (m :: * -> *). MonadIO m => TreePath -> m [Int32]
    treePathGetIndices' TreePath
    path
      store@Store { depth = d, content = cache } <-
          readIORef (customStoreGetPrivate (CustomStore model))
      case fromPath d ipath of
        (Just ForestStoreIter
    iter) -> do
          let (Bool
    res, Cache a
    cache') = Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    forall a. Depth -> ForestStoreIter -> Cache a -> (Bool, Cache a)
    checkSuccess Depth
    d ForestStoreIter
    iter Cache a
    cache
          IORef (Store a) -> Store a -> IO ()
    forall a. IORef a -> a -> IO ()
    writeIORef (CustomStore (IORef (Store a)) a -> IORef (Store a)
    forall private row. CustomStore private row -> private
    customStoreGetPrivate (ManagedPtr (CustomStore (IORef (Store a)) a)
    -> CustomStore (IORef (Store a)) a
    forall private row.
    ManagedPtr (CustomStore private row) -> CustomStore private row
    CustomStore ManagedPtr (CustomStore (IORef (Store a)) a)
    model)) Store a
    store { content = cache' }
          case Cache a
    cache' of
            ((ForestStoreIter
    _,Tree a
    node:Forest a
    _):Cache a
    _) | Bool
    res -> Maybe (Tree a) -> IO (Maybe (Tree a))
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Tree a -> Maybe (Tree a)
    forall a. a -> Maybe a
    Just Tree a
    node)
            Cache a
    _ -> Maybe (Tree a) -> IO (Maybe (Tree a))
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Tree a)
    forall a. Maybe a
    Nothing
        Maybe ForestStoreIter
    _ -> Maybe (Tree a) -> IO (Maybe (Tree a))
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Tree a)
    forall a. Maybe a
    Nothing