diff --git a/hw-prim.cabal b/hw-prim.cabal
--- a/hw-prim.cabal
+++ b/hw-prim.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 9557d04243ece405165f6a9004bb89861952430c1af773a2563ac554b528a5f5
+-- hash: 11d67b82027bbd9c1976068da2b796996ee055df323f0e38133562dfe9a669a4
 
 name:           hw-prim
-version:        0.5.0.4
+version:        0.5.0.5
 synopsis:       Primitive functions and data types
 description:    Please see README.md
 category:       Data
@@ -27,6 +27,11 @@
   type: git
   location: https://github.com/haskell-works/hw-prim
 
+flag bounds-checking-enabled
+  description: Enable bmi2 instruction set
+  manual: False
+  default: False
+
 library
   hs-source-dirs:
       src
@@ -36,6 +41,8 @@
     , bytestring
     , mmap
     , vector
+  if flag(bounds-checking-enabled)
+    cpp-options: -DBOUNDS_CHECKING_ENABLED
   exposed-modules:
       HaskellWorks.Data.AtIndex
       HaskellWorks.Data.ByteString
@@ -87,6 +94,8 @@
     , hw-prim
     , mmap
     , vector
+  if flag(bounds-checking-enabled)
+    cpp-options: -DBOUNDS_CHECKING_ENABLED
   other-modules:
       HaskellWorks.Data.FromByteStringSpec
       HaskellWorks.Data.FromForeignRegionSpec
@@ -107,6 +116,8 @@
     , hw-prim
     , mmap
     , vector
+  if flag(bounds-checking-enabled)
+    cpp-options: -DBOUNDS_CHECKING_ENABLED
   other-modules:
       Paths_hw_prim
   default-language: Haskell2010
diff --git a/src/HaskellWorks/Data/AtIndex.hs b/src/HaskellWorks/Data/AtIndex.hs
--- a/src/HaskellWorks/Data/AtIndex.hs
+++ b/src/HaskellWorks/Data/AtIndex.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP                   #-}
 {-# LANGUAGE FlexibleInstances     #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE TypeFamilies          #-}
@@ -6,6 +7,8 @@
     ( Container(..)
     , AtIndex(..)
     , Length(..)
+    , (?!?)
+    , (?!$)
     , atIndexOr
     , atIndexOrLastOr
     ) where
@@ -31,112 +34,221 @@
   {-# INLINE atIndex #-}
 
 instance AtIndex BS.ByteString where
-  (!!!)   v i = v `BS.index` fromIntegral i
+  (!!!)   v i = BS.index v (fromIntegral i)
   atIndex v i = BS.index v (fromIntegral i)
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DV.Vector Word8) where
-  (!!!)   v i = v DV.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DV.unsafeIndex v (fromIntegral i)
   atIndex v i = DV.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DV.! fromIntegral i
+  atIndex v i = v DV.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DV.Vector Word16) where
-  (!!!)   v i = v DV.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DV.unsafeIndex v (fromIntegral i)
   atIndex v i = DV.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DV.! fromIntegral i
+  atIndex v i = v DV.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DV.Vector Word32) where
-  (!!!)   v i = v DV.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DV.unsafeIndex v (fromIntegral i)
   atIndex v i = DV.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DV.! fromIntegral i
+  atIndex v i = v DV.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DV.Vector Word64) where
-  (!!!)   v i = v DV.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DV.unsafeIndex v (fromIntegral i)
   atIndex v i = DV.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DV.! fromIntegral i
+  atIndex v i = v DV.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DVS.Vector Word8) where
-  (!!!)   v i = v DVS.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DVS.unsafeIndex v (fromIntegral i)
   atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DVS.! fromIntegral i
+  atIndex v i = v DVS.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DVS.Vector Word16) where
-  (!!!)   v i = v DVS.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DVS.unsafeIndex v (fromIntegral i)
   atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DVS.! fromIntegral i
+  atIndex v i = v DVS.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DVS.Vector Word32) where
-  (!!!)   v i = v DVS.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DVS.unsafeIndex v (fromIntegral i)
   atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DVS.! fromIntegral i
+  atIndex v i = v DVS.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DVS.Vector Word64) where
-  (!!!)   v i = v DVS.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DVS.unsafeIndex v (fromIntegral i)
   atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DVS.! fromIntegral i
+  atIndex v i = v DVS.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DV.Vector Int8) where
-  (!!!)   v i = v DV.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DV.unsafeIndex v (fromIntegral i)
   atIndex v i = DV.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DV.! fromIntegral i
+  atIndex v i = v DV.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DV.Vector Int16) where
-  (!!!)   v i = v DV.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DV.unsafeIndex v (fromIntegral i)
   atIndex v i = DV.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DV.! fromIntegral i
+  atIndex v i = v DV.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DV.Vector Int32) where
-  (!!!)   v i = v DV.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DV.unsafeIndex v (fromIntegral i)
   atIndex v i = DV.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DV.! fromIntegral i
+  atIndex v i = v DV.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DV.Vector Int64) where
-  (!!!)   v i = v DV.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DV.unsafeIndex v (fromIntegral i)
   atIndex v i = DV.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DV.! fromIntegral i
+  atIndex v i = v DV.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DVS.Vector Int8) where
-  (!!!)   v i = v DVS.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DVS.unsafeIndex v (fromIntegral i)
   atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DVS.! fromIntegral i
+  atIndex v i = v DVS.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DVS.Vector Int16) where
-  (!!!)   v i = v DVS.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DVS.unsafeIndex v (fromIntegral i)
   atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DVS.! fromIntegral i
+  atIndex v i = v DVS.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DVS.Vector Int32) where
-  (!!!)   v i = v DVS.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DVS.unsafeIndex v (fromIntegral i)
   atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DVS.! fromIntegral i
+  atIndex v i = v DVS.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DVS.Vector Int64) where
-  (!!!)   v i = v DVS.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DVS.unsafeIndex v (fromIntegral i)
   atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DVS.! fromIntegral i
+  atIndex v i = v DVS.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
 
 instance AtIndex (DVS.Vector Int) where
-  (!!!)   v i = v DVS.! fromIntegral i
+#if !defined(BOUNDS_CHECKING_ENABLED)
+  (!!!)   v i = DVS.unsafeIndex v (fromIntegral i)
   atIndex v i = DVS.unsafeIndex v (fromIntegral i)
+#else
+  (!!!)   v i = v DVS.! fromIntegral i
+  atIndex v i = v DVS.! fromIntegral i
+#endif
   {-# INLINE (!!!)   #-}
   {-# INLINE atIndex #-}
+
+-- | Get the element of the container at the specified position, but return the  default value
+-- `d` if the position is out of bounds.
+(?!?) :: AtIndex v => Elem v -> Elem v -> v -> Position -> Elem v
+(?!?) d e v vi = if vi >= 0
+  then if vi < end v
+    then v !!! vi
+    else e
+  else d
+{-# INLINE (?!?) #-}
+
+-- | Get the element of the container at the specified position, but return the last element
+-- if the position is past the end of the container or the default value `d` if the position
+-- is before the beginning of the vector.
+-- In the case when the container is empty, then the default value `d` is used.
+(?!$) :: (AtIndex v, Length v) => Elem v -> v -> Position -> Elem v
+(?!$) d v vi = if vi >= 0
+  then if vi < end v
+    then v !!! vi
+    else if end v == 0
+      then d
+      else v !!! (end v - 1)
+  else d
+{-# INLINE (?!$) #-}
 
 atIndexOr :: AtIndex v => Elem v -> v -> Position -> Elem v
 atIndexOr d v vi = if vi >= 0 && vi < end v
