//Programed by NAS6 //NAS6_cntn_ptr.h #pragma once #ifndef NAS6_RELEASE_BLD #define NAS6_CNTN_PTR_TEST #endif #include using namespace std; namespace NAS6_Utl { template class NAS6_cntn_ptr { protected: static T m_dummy; T* m_ptr; int m_current; NAS6_cntn_ptr* m_owner; int m_size; bool m_peeper; virtual NAS6_cntn_ptr& setowner(NAS6_cntn_ptr* rh) { m_owner = rh; return (*this); } virtual NAS6_cntn_ptr& setsize(int rh) { m_size = rh; return (*this); } virtual NAS6_cntn_ptr& setptr(T* rh) { m_ptr = rh; return (*this); } public: bool m_delptr; //コンストラクタ、デストラクタ //peeper = true : 覗き見ポインタ //delptr = true : 自動メモリ解放 //len : サイズ NAS6_cntn_ptr(bool peeper = false, bool delptr = true) { m_owner = this; m_current = 0; m_ptr = nullptr; m_size = 0; m_peeper = peeper; m_delptr = delptr; #ifdef NAS6_CNTN_PTR_TEST cout << "called NAS6_cntn_ptr::constructor peeper = "; if (m_peeper) cout << "true" << endl; else cout << "false" << endl; #endif } NAS6_cntn_ptr(int len, bool delptr = true) : NAS6_cntn_ptr() { if (m_peeper || len < 0) { return; } m_ptr = new T[len]; m_size = len; m_delptr = delptr; } NAS6_cntn_ptr(NAS6_cntn_ptr* rh) : NAS6_cntn_ptr(*rh) { ; } NAS6_cntn_ptr(NAS6_cntn_ptr& rh) { m_owner = rh.m_owner; m_current = rh.m_current; m_ptr = rh.m_ptr; m_size = rh.m_size; m_peeper = true; m_delptr = rh.m_delptr; #ifdef NAS6_CNTN_PTR_TEST cout << "called NAS6_cntn_ptr::copy constructor peeper = true" << endl; #endif } virtual ~NAS6_cntn_ptr() { if (m_delptr && !m_peeper && m_owner == this && m_ptr != nullptr) { delete[] m_ptr; m_ptr = nullptr; m_current = 0; m_size = 0; #ifdef NAS6_CNTN_PTR_TEST cout << "called NAS6_cntn_ptr::destructor" << endl; #endif } } //セットピーパー : 設定は慎重に行ってください virtual NAS6_cntn_ptr& setpeeper(bool rh) { m_peeper = rh; return (*this); } //カレント virtual int current() { return m_current; } //サイズ virtual int size() { return m_size; } //ポインタ virtual T* ptr() { return m_ptr; } //オーナー virtual NAS6_cntn_ptr* owner() { return m_owner; } //ピーパー virtual bool peeper() { return m_peeper; } //利用メモリ割り当て&メモリ所有権新規取得 virtual NAS6_cntn_ptr& assign(T* rh, const int len) { if (len < 0) return (*this); if (!m_peeper && m_delptr && m_ptr != nullptr) delete[] m_ptr; m_peeper = false; m_owner = this; m_ptr = rh; m_size = len; begin(); #ifdef NAS6_CNTN_PTR_TEST cout << "called NAS6_cntn_ptr::assign" << endl; #endif return (*this); } //リサイズ //force = true : 強制 : コピー&リサイズ&メモリ所有権新規取得 virtual NAS6_cntn_ptr& resize(const int len, const bool force = false) { if (m_peeper) return (*this); if (len < 0) return (*this); int i; int m = (len < m_size ? len : m_size); if (force || m_owner == this) { if (force) { m_owner = this; #ifdef NAS6_CNTN_PTR_TEST cout << "called NAS6_cntn_ptr::resize force" << endl; #endif } T* tmp = new T[len]; for (i = 0; i < m; i++) tmp[i] = m_ptr[i]; for (; i < len; i++) tmp[i] = T(); if (m_ptr != nullptr) delete[] m_ptr; m_ptr = tmp; m_size = len; begin(); } return (*this); } //リムーブ virtual NAS6_cntn_ptr& remove(const int rh) { if (m_peeper) return (*this); if (rh < 0 || m_size <= rh) return (*this); int i; int j; if (m_owner == this) { T* tmp = new T[m_size - 1]; for (i = 0, j = 0; i < m_size; i++) { if (i == rh) { j++; } else { tmp[i - j] = m_ptr[i]; } } if (m_ptr != nullptr) delete[] m_ptr; m_ptr = tmp; m_size = m_size - 1; begin(); #ifdef NAS6_CNTN_PTR_TEST cout << "called NAS6_cntn_ptr::remove" << endl; #endif } return (*this); } //アッド virtual NAS6_cntn_ptr& add(const int rh, T& trh) { if (m_peeper) return (*this); if (rh < 0 || m_size < rh) return (*this); int i; if (m_owner == this) { T* tmp = new T[m_size + 1]; for (i = 0; i < rh; i++) { tmp[i] = m_ptr[i]; } tmp[i] = trh; i++; for (; i < m_size + 1; i++) { tmp[i] = m_ptr[i - 1]; } if (m_ptr != nullptr) delete[] m_ptr; m_ptr = tmp; m_size = m_size + 1; begin(); #ifdef NAS6_CNTN_PTR_TEST cout << "called NAS6_cntn_ptr::add" << endl; #endif } return (*this); } //コピー&リサイズ&メモリ所有権新規取得 : peeper = true : rhを覗き見ポインタにする : destroy = true : rhをアクセス不可にする virtual NAS6_cntn_ptr& copyFrom(NAS6_cntn_ptr& rh, int len = -1, bool peeper = false, bool destroy = false) { if (m_peeper) return (*this); if (len < 0) len = rh.m_size; int i; int m = (len < rh.m_size ? len : rh.m_size); if (rh.m_owner == &(rh) && rh.m_ptr != nullptr) { #ifdef NAS6_CNTN_PTR_TEST cout << "called NAS6_cntn_ptr::copyFrom" << endl; #endif T* tmp = new T[len]; m_owner = this; for (i = 0; i < m; i++) tmp[i] = rh[i]; for (; i < len; i++) tmp[i] = T(); if (m_ptr != nullptr) delete[] m_ptr; m_ptr = tmp; m_size = len; begin(); if (destroy) { if (&rh != this && !rh.m_peeper && rh.m_delptr && rh.m_ptr != nullptr) delete[] rh.m_ptr; rh.m_peeper = true; rh.m_ptr = nullptr; rh.m_owner = nullptr; rh.m_size = 0; rh.m_current = 0; } else if (peeper) { if (&rh != this && !rh.m_peeper && rh.m_delptr && rh.m_ptr != nullptr) delete[] rh.m_ptr; rh.m_peeper = true; rh.m_ptr = m_ptr; rh.m_owner = this; rh.m_size = m_size; rh.m_current = m_current; } } return (*this); } //指示メモリにゃむにゃむ virtual NAS6_cntn_ptr& begin() { if (m_ptr != nullptr) { if (!m_peeper && m_owner != this) { return (*this); } m_current = 0; } return (*this); } virtual NAS6_cntn_ptr& end() { if (m_ptr != nullptr) { if (!m_peeper && m_owner != this) { return (*this); } m_current = m_size - 1; } return (*this); } virtual NAS6_cntn_ptr& at(const int rh) { if (!m_peeper && m_owner != this) { return (*this); } if (m_ptr != nullptr && 0 <= rh && rh <= m_size) { m_current = rh; } return (*this); } //代入、メモリ所有権移譲 virtual NAS6_cntn_ptr& operator =(NAS6_cntn_ptr& rh) { if (!m_peeper && m_ptr != nullptr) delete[] m_ptr; if (rh.m_ptr != nullptr) { if (m_peeper) { m_ptr = rh.m_ptr; m_owner = &(rh); m_size = rh.m_size; at(rh.m_current); } else { m_ptr = rh.m_ptr; m_owner = this; m_size = rh.m_size; at(rh.m_current); rh.m_owner = &rh; rh.m_current = 0; rh.m_ptr = nullptr; rh.m_size = 0; } } else { m_owner = this; m_current = 0; m_ptr = nullptr; m_size = 0; } return (*this); } //演算子にゃむにゃむ virtual NAS6_cntn_ptr& operator ++(int rh) { if (!m_peeper && m_owner != this) { return (*this); } if (!rh) { rh = 1; } return ((*this) + rh); } virtual NAS6_cntn_ptr& operator --(int rh) { if (!m_peeper && m_owner != this) { return (*this); } if (!rh) { rh = 1; } return ((*this) - rh); } virtual NAS6_cntn_ptr& operator +(const int rh) { if ((!m_peeper && m_owner != this) || !rh) { return (*this); } if (m_ptr != nullptr && 0 <= m_current + rh && m_current + rh <= m_size) { at(m_current + rh); } return (*this); } virtual NAS6_cntn_ptr& operator -(const int rh) { if ((!m_peeper && m_owner != this) || !rh) { return (*this); } if (m_ptr != nullptr && 0 <= m_current - rh && m_current - rh <= m_size) { at(m_current - rh); } return (*this); } friend NAS6_cntn_ptr& operator ++(NAS6_cntn_ptr& rh) { if (!rh.m_peeper && rh.m_owner != &rh) { return rh; } if (rh.m_ptr != nullptr && 0 <= rh.m_current + 1 && rh.m_current + 1 <= rh.m_size) { rh.at(rh.m_current + 1); } return rh; } friend NAS6_cntn_ptr& operator --(NAS6_cntn_ptr& rh) { if !rh.m_peeper && (rh.m_owner != &rh) { return rh; } if (rh.m_ptr != nullptr && 0 <= rh.m_current - 1 && rh.m_current - 1 <= rh.m_size) { rh.at(rh.m_current - 1); } return rh; } virtual T* operator ->() const { if (!m_peeper && m_owner != this) { return nullptr; } if (m_ptr != nullptr && 0 <= m_current && m_current < m_size) { return &(*(*this)); } return nullptr; } virtual T& operator [](const int rh) const { if (!m_peeper && m_owner != this) { return m_dummy; } if (m_ptr != nullptr && 0 <= rh && rh < m_size) { return (m_ptr[rh]); } return m_dummy; } friend T& operator *(const NAS6_cntn_ptr& rh) { if (!rh.m_peeper && rh.m_owner != &rh) { return m_dummy; } if (rh.m_ptr != nullptr && 0 <= rh.m_current && rh.m_current < rh.m_size) { return (rh.m_ptr[rh.m_current]); } return m_dummy; } }; //ダミー実体 template T NAS6_cntn_ptr::m_dummy; }