排序自定义容器(实现为一个整数)

时间:2017-06-18 06:34:51

标签: c++ sorting bit-manipulation

我有一个类,它在较大的整数变量中包含小数字。它运行良好,速度快,看起来像这样:

template
class Container<IntegerT>
  static int bitsPerElement;
  IntegerT data; // [0000] [0000] [0000] [0000] up to 128bits(or maybe more)
  int size;

iterator as value_type return&#34; reference&#34;到容器元素:

Container::iterator
  DataRef operator*()

DataRef
  Container* parent;
  int position;

但是我遇到了std :: sort不可用的问题,因为它不知道如何实际交换这个容器的元素(直接交换DataRef显然没有意义)。

是否有任何神奇的方法使std :: sort与它一起工作(实际上是强制它使用自定义交换功能)?

或者是否可以替代std :: sort来处理这种情况? (将DataRefs存储在数组中不被视为解决方案)

哪种方法可以对此数据结构进行排序?

#ifndef INTSTORAGE_H
#define INTSTORAGE_H

#include <algorithm>

template<class T> class IntStorage;

template<class T>
class DataRef
{
  public:
    DataRef(IntStorage<T>* parent, int position) : m_parent(parent), m_position(position) {}
    DataRef(DataRef&& o) = default;
    DataRef(const DataRef& o) = default;

    int value() const {return m_parent->value(m_position);}
    void setValue(int value) {m_parent->setValue(m_position, value);}

    DataRef& operator=(const DataRef& c)
    { setValue(c.value()); return *this; }
    DataRef& operator=(const DataRef&& c)
    { setValue(c.value()); return *this; }
    bool operator<(const DataRef& o) const
    { return value() <  o.value(); }

    IntStorage<T>* m_parent;
    int m_position;
};

template<class T>
class IntStorage
{
    template<typename> friend class IntStorage;
    template<typename> friend class DataRef;
  public:
    void append(int value)
    {
      data |= (static_cast<T>(value) << (s_bitsPerItem * size));
      ++size;
    }

    void setValue(int index, T value)
    {
      data = ((~(s_mask << (s_bitsPerItem * index))) & data)
             | (static_cast<T>(value) << (s_bitsPerItem * index));
    }
    T value(int i) const { return (data & s_mask << (i * s_bitsPerItem)) >> (i * s_bitsPerItem); }

    class iterator
    {
      public:
        using iterator_category = std::random_access_iterator_tag;
        using difference_type = int;
        using value_type = DataRef<T>;
        using pointer = DataRef<T>*;
        using reference = DataRef<T>&;

        iterator(IntStorage<T>* parent, int pos = 0) : ref(parent, pos) {}
        inline bool operator==(const iterator& o) const { return ref.m_parent == o.ref.m_parent && ref.m_position == o.ref.m_position;}
        inline bool operator!=(const iterator& o) const { return !operator==(o);}
        inline const DataRef<T>& operator*() const {  return ref;}
        inline DataRef<T>& operator*() { return ref; }
        inline iterator& operator++() { ++ref.m_position; return *this; }
        inline iterator& operator--() { --ref.m_position; return *this; }
        inline int operator-(const iterator& o) const {  return ref.m_position - o.ref.m_position; }
        inline iterator operator+(int diff) const {  return iterator(ref.m_parent, ref.m_position + diff); }
        inline iterator operator-(int diff) const {  return iterator(ref.m_parent, ref.m_position - diff); }
        inline bool operator<(const iterator& o) const {  return ref.m_position < o.ref.m_position; }
        DataRef<T> ref;
    };
    friend class iterator;

    iterator begin()  {return iterator(this, 0);}
    iterator end()    {return iterator(this, size);}
    iterator cbegin() {return iterator(this, 0);}
    iterator cend()   {return iterator(this, size);}

    static constexpr T s_mask = 0b111111;
    static constexpr int s_bitsPerItem = 6;
    int size = 0;
    T data = 0;
};

#endif // INTSTORAGE_H

0 个答案:

没有答案