beginner – dynamic queue implementation in C++

Hello everyone I’ve implemented a dynamic queue along side with a randkm access iterator, can I get a review ? And thanks in advance.

iterator:

#pragma once
#include <iterator>

namespace con {
template <class T> class rnd_iterator {
  T *m_Ptr;

public:
  /*
   * type aliases
   */
  using value_type = T;
  using iterator_type = rnd_iterator<value_type>;
  using iterator_category = std::random_access_iterator_tag;
  using pointer = value_type *;
  using const_pointer = const pointer;
  using difference_type = std::ptrdiff_t;
  using reference = value_type &;
  using const_reference = const value_type &;
  /*
   * constructors
   */
  rnd_iterator(const rnd_iterator<T> &other) noexcept : m_Ptr(other.m_Ptr) {}
  rnd_iterator(T *p) noexcept : m_Ptr(p) {}
  /*
   * access operators
   */
  reference operator*() { return *m_Ptr; }
  reference operator()(std::size_t idx) { return m_Ptr(idx); }
  pointer operator->() { return m_Ptr; }
  /*
   * increment/decrement and assign operators
   */
  rnd_iterator &operator=(pointer oth) {
    m_Ptr = oth;
    return *this;
  }
  rnd_iterator &operator+=(pointer oth) {
    m_Ptr += oth;
    return *this;
  }
  rnd_iterator &operator-=(pointer oth) {
    m_Ptr -= oth;
    return *this;
  }
  iterator_type &operator=(const iterator_type &rhs) {
    m_Ptr = rhs.m_Ptr;
    return *this;
  }
  friend iterator_type &operator+=(const iterator_type &lhs,
                                   const iterator_type &rhs) {
    lhs.m_Ptr += rhs.m_Ptr;
    return lhs;
  }
  friend iterator_type &operator-=(const iterator_type &lhs,
                                   const iterator_type &rhs) {
    lhs.m_Ptr -= rhs.m_Ptr;
    return lhs;
  }
  rnd_iterator operator++() {
    ++m_Ptr;
    return *this;
  }
  rnd_iterator operator++(int) {
    auto temp = *this;
    m_Ptr++;
    return temp;
  }
  rnd_iterator &operator--() {
    --m_Ptr;
    return *this;
  }
  rnd_iterator operator--(int) {
    auto temp = *this;
    m_Ptr--;
    return temp;
  }
  /*
   * comparison operators
   */
  friend bool operator!=(const iterator_type &lhs, const iterator_type &rhs) {
    return lhs.m_Ptr != rhs.m_Ptr;
  }
  friend bool operator!=(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr != rhs;
  }
  friend bool operator==(const iterator_type &lhs, const iterator_type &rhs) {
    return lhs.m_Ptr == rhs.m_Ptr;
  }
  friend bool operator==(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr == rhs;
  }
  friend bool operator<(const iterator_type &lhs, const iterator_type &rhs) {
    return lhs.m_Ptr < rhs.m_Ptr;
  }
  friend bool operator<(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr < rhs;
  }
  friend bool operator<=(const iterator_type &lhs, const iterator_type &rhs) {
    return lhs.m_Ptr <= rhs.m_Ptr;
  }
  friend bool operator<=(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr <= rhs;
  }
  friend bool operator>(const iterator_type &lhs, const iterator_type &rhs) {
    return lhs.m_Ptr > rhs.m_Ptr;
  }
  friend bool operator>(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr > rhs;
  }
  friend bool operator>=(const iterator_type &lhs, const iterator_type &rhs) {
    return lhs.m_Ptr >= rhs.m_Ptr;
  }
  friend bool operator>=(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr >= rhs;
  }
  friend difference_type operator+(const iterator_type &lhs,
                                   const iterator_type &rhs) {
    return lhs.m_Ptr + rhs.m_Ptr;
  }
  friend difference_type operator+(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr + rhs;
  }
  friend iterator_type operator+(const iterator_type &lhs,
                                 difference_type rhs) {
    return lhs.m_Ptr + rhs;
  }
  friend difference_type operator-(const iterator_type &lhs,
                                   const iterator_type &rhs) {
    return lhs.m_Ptr - rhs.m_Ptr;
  }
  friend iterator_type operator-(const iterator_type &lhs,
                                 difference_type rhs) {
    return lhs.m_Ptr - rhs;
  }
  friend difference_type operator-(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr - rhs;
  }
};
}

queue:

#pragma once
#include "iterator.hpp"
#include <algorithm>
#include <cassert>
#include <initializer_list>
#include <iostream>
#include <iterator>
#include <limits>
#include <memory>
#include <type_traits>
#include <utility>

namespace con {
template <class T, class Allocator = std::allocator<T>> class queue {
  Allocator m_Alloc;
  std::size_t m_Size, m_Capacity;
  std::allocator_traits<Allocator> m_AllocTraits;
  T *m_RawData;
  void m_ReallocAnyway(std::size_t t_NewCapacity) {
    std::size_t f_old = m_Capacity;
    T *f_temp = m_Alloc.allocate(sizeof(T) * t_NewCapacity);
    try {
      for (std::size_t i = 0; i < m_Size; i++) {
        new (&f_temp(i)) T(std::move_if_noexcept(m_RawData(i)));
        m_AllocTraits.destroy(m_Alloc, std::addressof(m_RawData(i)));
      }
      m_Alloc.deallocate(m_RawData, f_old);
      m_RawData = f_temp;
    } catch (const std::exception &exc) {
      m_Alloc.deallocate(f_temp, sizeof(T) * t_NewCapacity);
      throw std::move(exc);
    }
  }
  void m_Realloc(std::size_t t_NewCapacity) {
    if (t_NewCapacity > m_Capacity) {
      m_ReallocAnyway(t_NewCapacity);
    } else {
      return;
    }
  }
  void m_ShiftToLeft() {
    for (std::size_t i = 0; i < m_Size; i++) {
      new (&m_RawData(i)) T(std::move_if_noexcept(m_RawData(i + 1)));
    }
  }
  template <class F>
  void m_ShiftFromTo(std::size_t from, std::size_t to, F &&func) {
    for (; from < to; from++) {
      new (&m_RawData(from))
          T(std::move_if_noexcept(m_RawData(func(from, to))));
    }
  }
  template <class It> void m_ShiftRangeFromTo(It from, It to) {
    for (; from != to; from++) {
      new (std::addressof(*from))
          T(std::move_if_noexcept(*(from + (to - from))));
    }
  }
  template <class Iter> void m_DestroyRange(Iter beg, Iter end) {
    for (; beg != end; beg++) {
      m_AllocTraits.destroy(m_Alloc, std::addressof(*beg));
    }
  }
  void m_CheckOrAlloc(std::size_t t_Size) {
    if (t_Size >= m_Capacity) {
      m_Realloc(m_Capacity * 2);
    }
  }

public:
  using value_type = T;
  using allocator_type = Allocator;
  using size_type = decltype(m_Size);
  using difference_type = std::ptrdiff_t;
  using reference = value_type &;
  using const_reference = const value_type &;
  using pointer = typename std::allocator_traits<Allocator>::pointer;
  using const_pointer =
      typename std::allocator_traits<Allocator>::const_pointer;
  using iterator = con::rnd_iterator<value_type>;
  using const_iterator = const iterator;
  using reverse_iterator = std::reverse_iterator<iterator>;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;

  explicit queue(size_type cap = (sizeof(value_type) * 5),
                 const Allocator &alloc = Allocator{}) noexcept
      : m_Alloc(alloc), m_Size(0), m_Capacity(cap),
        m_RawData(m_Alloc.allocate(m_Capacity)) {}
  explicit queue(const std::initializer_list<T> &init,
                 const Allocator &alloc = Allocator{}) noexcept
      : m_Alloc(alloc), m_Size(init.size()), m_Capacity(sizeof(value_type) * 5),
        m_RawData(m_Alloc.allocate(m_Capacity)) {
    m_Size = init.size();
    m_CheckOrAlloc(m_Size);
    std::uninitialized_copy(init.begin(), init.end(), m_RawData);
  }
  explicit queue(const queue<value_type> &oth) : queue() {
    if (std::is_destructible<value_type>::value)
      clear();
    m_Size = oth.size();
    m_CheckOrAlloc(m_Size);
    std::uninitialized_copy(oth.begin(), oth.end(), m_RawData);
  }
  explicit queue(queue<value_type> &&oth) noexcept : queue() {
    if (std::is_destructible<value_type>::value)
      clear();
    m_Size = oth.size();
    m_CheckOrAlloc(m_Size);
    std::uninitialized_move(oth.begin(), oth.end(), m_RawData);
  }
  template <class It> queue(It begin, It end) noexcept : queue() {
    assert(begin <= end);
    size_type f_size = std::distance(begin, end);
    m_CheckOrAlloc(f_size);
    m_Size = f_size;
    std::uninitialized_copy(begin, end, m_RawData);
  }
  explicit queue(const queue<value_type> &&oth) = delete;
  iterator begin() noexcept { return iterator(m_RawData); }
  iterator end() noexcept { return iterator(m_RawData + size()); }
  reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
  reverse_iterator rend() noexcept { return reverse_iterator(begin()); }

  const_iterator begin() const noexcept { return const_iterator(m_RawData); }
  const_iterator end() const noexcept {
    return const_iterator(m_RawData + size());
  }
  const_reverse_iterator rbegin() const noexcept {
    return const_reverse_iterator(m_RawData + size());
  }
  const_reverse_iterator rend() const noexcept {
    return const_reverse_iterator(m_RawData);
  }

  const_iterator cbegin() const noexcept { return const_iterator(m_RawData); }
  const_iterator cend() const noexcept {
    return const_iterator(m_RawData + size());
  }
  const_reverse_iterator crbegin() const noexcept { return rbegin(); }
  const_reverse_iterator crend() const noexcept { rend(); }

  bool empty() const noexcept { return size() == 0; }
  size_type size() const noexcept { return m_Size; }
  size_type capacity() const noexcept { return m_Capacity; }
  size_type max_capacity() const noexcept {
    return std::numeric_limits<size_type>::max();
  }
  const_pointer data() const { return m_RawData; }
  void clear() requires(std::is_destructible<value_type>::value) {
    for (size_type i = 0; i < size(); i++) {
      m_AllocTraits.destroy(m_Alloc, std::addressof(m_RawData(i)));
    }
    m_Size = 0;
  }
  void reserve(size_type cp) { m_CheckOrAlloc(cp); }
  void resize(size_type sz) {
    m_Size = sz;
    m_CheckOrAlloc(sz);
  }
  void erase(iterator val) {
    if (val != end()) {
      difference_type x = val - begin();
      pointer p = m_RawData + x;
      m_AllocTraits.destroy(m_Alloc, std::addressof(*val));
      m_ShiftFromTo(std::distance(begin(), iterator(p)), size(),
                    ()(auto l, ((maybe_unused)) auto _) { return l + 1; });
      m_Size--;
    } else {
      return;
    }
  }
  void erase(iterator first, iterator last) {
    assert(first <= last && "queue::erase invalid range");
    m_DestroyRange(first, last);
    m_ShiftRangeFromTo(first, last);
    m_Size -= std::distance(first, last);
  }
  void erase(reverse_iterator first, reverse_iterator last) {
    assert(first <= last && "queue::erase invalid range");
    m_DestroyRange(first, last);
    m_ShiftRangeFromTo(first, last);
    m_Size -= std::distance(first, last);
  }
  void erase(reverse_iterator val) {
    if (val != rend()) {
      m_AllocTraits.destroy(m_Alloc, std::addressof(*val));
      m_ShiftFromTo(std::distance(val, rend()) - 1, size(),
                    ()(auto l, ((maybe_unused)) auto _) { return l + 1; });
      m_Size--;
    } else {
      return;
    }
  }
  void erase(const value_type &obj) { erase(std::find(begin(), end(), obj)); }
  void rerase(const value_type &obj) {
    erase(std::find(rbegin(), rend(), obj));
  }
  iterator find(const value_type &obj) {
    return std::find(begin(), end(), obj);
  }
  reverse_iterator rfind(const value_type &obj) {
    return std::find(rbegin(), rend(), obj);
  }
  const_iterator find(const_reference obj) const {
    return std::find(begin(), end(), obj);
  }
  const_reverse_iterator rfind(const value_type &obj) const {
    return std::find(rbegin(), rend(), obj);
  }

  void enqueue(const value_type &oth) requires(
      std::is_copy_constructible<value_type>::value) {
    m_CheckOrAlloc(size());
    new (&m_RawData(m_Size++)) value_type(oth);
  }
  void enqueue(value_type &&oth) requires(
      std::is_move_constructible<value_type>::value) {
    m_CheckOrAlloc(size());
    new (&m_RawData(m_Size++)) value_type(std::move(oth));
  }
  ((nodiscard)) value_type
  dequeue() requires(std::is_destructible<value_type>::value) {
    --m_Size;
    value_type temp = m_RawData(0);
    m_AllocTraits.destory(m_Alloc, std::addressof(m_RawData(0)));
    m_ShiftToLeft();
    return temp;
  }
  template <class... Args> void emplace(Args &&...args) {
    enqueue(value_type(std::forward<Args>(args)...));
  }
  value_type at(size_type index) const {
    if (index >= size()) {
      throw std::range_error("out of bounds queue"); // yes helpful error
    } else {
      return m_RawData(index);
    }
  }
  reference at(size_type index) {
    if (index >= size()) {
      throw std::range_error("out of bounds queue"); // yes helpful error
    } else {
      return m_RawData(index);
    }
  }
  value_type operator()(size_type index) const { return m_RawData(index); }
  reference operator()(size_type index) { return m_RawData(index); }

  queue<value_type> &operator=(const queue<value_type> &oth) {
    if (&oth != this) {
      clear();
      m_Size = oth.size();
      m_CheckOrAlloc(m_Size);
      std::uninitialized_copy(oth.begin(), oth.end(), m_RawData);
    }
    return *this;
  }
  queue<value_type> &operator=(queue<value_type> &&oth) {
    if (&oth != this) {
      clear();
      m_Size = oth.size();
      m_CheckOrAlloc(m_Size);
      std::uninitialized_move(oth.begin(), oth.end(), m_RawData);
      oth.~queue();
    }
    return *this;
  }
  queue<value_type> &operator=(const queue<value_type> &&oth) = delete;
  ~queue() {
    m_Alloc.deallocate(m_RawData, m_Capacity);
    std::exchange(m_RawData, nullptr);
    std::exchange(m_Size, 0);
  }
  ~queue() requires(std::is_destructible<value_type>::value) {
    clear();
    m_Alloc.deallocate(m_RawData, m_Capacity);
    std::exchange(m_RawData, nullptr);
    std::exchange(m_Size, 0);
  }
};
}
```