     buffer))
 
 (definterface+ IMikronByteBufferFactory
-  (^mikron.buffer.IMikronByteBuffer allocate* [^long size]    "Allocates a buffer with size `size`.")
-  (^mikron.buffer.IMikronByteBuffer wrap*     [^bytes binary] "Wraps a binary value `binary` with a buffer."))
+  (^mikron.buffer.IMikronByteBuffer -allocate [^long size]    "Allocates a buffer with size `size`.")
+  (^mikron.buffer.IMikronByteBuffer -wrap     [^bytes binary] "Wraps a binary value `binary` with a buffer."))
 
 (defn byte-buffer-factory?
   "Returns `true` if `value` is an instance of `IMikronByteBufferFactory`, `false` otherwise."

(defn get-bit-position
  "Gets the bit position of `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(get-bit-position* (get-bit-buffer ~buffer)))})
  ^long [^MikronBuffer buffer]
  (get-bit-position* (get-bit-buffer buffer)))

(defn set-bit-position
  "Sets the bit position of `buffer` to `value`."
  #?(:clj {:inline (fn [buffer value]
                     `(set-bit-position* (get-bit-buffer ~buffer) ~value))})
  [^MikronBuffer buffer ^long value]
  (set-bit-position* (get-bit-buffer buffer) value))

(defn get-bit-index
  "Gets the bit index of `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(get-bit-index* (get-bit-buffer ~buffer)))})
  ^long [^MikronBuffer buffer]
  (get-bit-index* (get-bit-buffer buffer)))

(defn set-bit-index
  "Sets the bit index of `buffer` to `value`."
  #?(:clj {:inline (fn [buffer value]
                     `(set-bit-index* (get-bit-buffer ~buffer) ~value))})
  [^MikronBuffer buffer ^long value]
  (set-bit-index* (get-bit-buffer buffer) value))

(defn get-bit-value
  "Gets the bit value of `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(get-bit-value* (get-bit-buffer ~buffer)))})
  ^long [^MikronBuffer buffer]
  (get-bit-value* (get-bit-buffer buffer)))

(defn set-bit-value
  "Sets the bit value of `buffer` to `value`."
  #?(:clj {:inline (fn [buffer value]
                     `(set-bit-value* (get-bit-buffer ~buffer) ~value))})
  [^MikronBuffer buffer ^long value]
  (set-bit-value* (get-bit-buffer buffer) value))

;; Public delegated operations

(defn take-byte
  "Takes a byte from `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(take-byte* (get-byte-buffer ~buffer)))})
  ^long [^MikronBuffer buffer]
  (take-byte* (get-byte-buffer buffer)))

(defn put-byte
  "Puts a byte `value` to `buffer`."
  #?(:clj {:inline (fn [buffer value]
                     `(put-byte* (get-byte-buffer ~buffer) ~value))})
  [^MikronBuffer buffer ^long value]
  (put-byte* (get-byte-buffer buffer) value))

(defn take-short
  "Takes a short from `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(take-short* (get-byte-buffer ~buffer)))})
  ^long [^MikronBuffer buffer]
  (take-short* (get-byte-buffer buffer)))

(defn put-short
  "Puts a short `value` to `buffer`."
  #?(:clj {:inline (fn [buffer value]
                     `(put-short* (get-byte-buffer ~buffer) ~value))})
  [^MikronBuffer buffer ^long value]
  (put-short* (get-byte-buffer buffer) value))

(defn take-int
  "Takes an int from `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(take-int* (get-byte-buffer ~buffer)))})
  ^long [^MikronBuffer buffer]
  (take-int* (get-byte-buffer buffer)))

(defn put-int
  "Puts an int `value` to `buffer`."
  #?(:clj {:inline (fn [buffer value]
                     `(put-int* (get-byte-buffer ~buffer) ~value))})
  [^MikronBuffer buffer ^long value]
  (put-int* (get-byte-buffer buffer) value))

(defn take-long
  "Takes a long from `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(take-long* (get-byte-buffer ~buffer)))})
  ^long [^MikronBuffer buffer]
  (take-long* (get-byte-buffer buffer)))

(defn put-long
  "Puts a long `value` to `buffer`."
  #?(:clj {:inline (fn [buffer value]
                     `(put-long* (get-byte-buffer ~buffer) ~value))})
  [^MikronBuffer buffer ^long value]
  (put-long* (get-byte-buffer buffer) value))

(defn take-float
  "Takes a float from `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(take-float* (get-byte-buffer ~buffer)))})
  ^double [^MikronBuffer buffer]
  (take-float* (get-byte-buffer buffer)))

(defn put-float
  "Puts a float `value` to `buffer`."
  #?(:clj {:inline (fn [buffer value]
                     `(put-float* (get-byte-buffer ~buffer) ~value))})
  [^MikronBuffer buffer ^double value]
  (put-float* (get-byte-buffer buffer) value))

(defn take-double
  "Takes a double from `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(take-double* (get-byte-buffer ~buffer)))})
  ^double [^MikronBuffer buffer]
  (take-double* (get-byte-buffer buffer)))

(defn put-double
  "Puts a double `value` to `buffer`."
  #?(:clj {:inline (fn [buffer value]
                     `(put-double* (get-byte-buffer ~buffer) ~value))})
  [^MikronBuffer buffer ^double value]
  (put-double* (get-byte-buffer buffer) value))

(defn take-bytes
  "Takes `n` bytes from `buffer`."
  #?(:clj {:inline (fn [buffer n]
                     `(take-bytes* (get-byte-buffer ~buffer) ~n))})
  ^bytes [^MikronBuffer buffer ^long n]
  (take-bytes* (get-byte-buffer buffer) n))

(defn put-bytes
  "Puts some bytes `value` to `buffer`."
  #?(:clj {:inline (fn [buffer value]
                     `(put-bytes* (get-byte-buffer ~buffer) ~value))})
  [^MikronBuffer buffer ^bytes value]
  (put-bytes* (get-byte-buffer buffer) value))

(defn take-bytes-all
  "Takes all bytes from `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(take-bytes-all* (get-byte-buffer ~buffer)))})
  ^bytes [^MikronBuffer buffer]
  (take-bytes-all* (get-byte-buffer buffer)))

(defn get-position
  "Gets the position of `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(get-position* (get-byte-buffer ~buffer)))})
  ^long [^MikronBuffer buffer]
  (get-position* (get-byte-buffer buffer)))

(defn set-position
  "Sets the position of `buffer`."
  #?(:clj {:inline (fn [buffer value]
                     `(set-position* (get-byte-buffer ~buffer) ~value))})
  [^MikronBuffer buffer ^long value]
  (set-position* (get-byte-buffer buffer) value))

(defn get-le
  "Gets the endianness of `buffer`."
  #?(:clj {:inline (fn [buffer]
                     `(get-le* (get-byte-buffer ~buffer)))})
  [^MikronBuffer buffer]
  (get-le* (get-byte-buffer buffer)))

(defn set-le
  "Sets the endianness of `buffer`."
  #?(:clj {:inline (fn [buffer value]
                     `(set-le* (get-byte-buffer ~buffer) ~value))})
  [^MikronBuffer buffer value]
  (set-le* (get-byte-buffer buffer) value))

;; Public derived operations



(deftype MikronByteBufferFactory []
  IMikronByteBufferFactory
  (-allocate [_ size]
    #?(:clj  (->MikronByteBuffer (.order (ByteBuffer/allocateDirect size) (ByteOrder/nativeOrder)))
       :cljs (->MikronByteBuffer (.allocUnsafe NativeJsBuffer size) 0 true)))
  (-wrap [_ binary]
    #?(:clj  (->MikronByteBuffer (ByteBuffer/wrap binary))
       :cljs (->MikronByteBuffer (.from NativeJsBuffer binary) 0 true))))

