220 34965 <7f22751b-91d1-4de4-81d2-421046ceb963@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Mingxin Wang <wmx16835vv@163.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Idea about "std::pmr::memory_resource"
Date: Mon, 16 Oct 2017 08:11:02 -0700 (PDT)
Lines: 601
Approved: news@gmane.org
Message-ID: <7f22751b-91d1-4de4-81d2-421046ceb963@isocpp.org>
References: <0a8293b4-3246-47a5-9881-bc1ca4b91772@isocpp.org>
 <07ddb1f6-d3af-43df-bf96-8975c1ab4313@isocpp.org>
 <2e191a96-1952-479b-b78b-22e31f8e03de@isocpp.org>
 <0e37b5ae-64f6-4a8a-86bd-f44b119ed40a@isocpp.org>
 <15f8c5ba-3a6a-4441-9620-92e157c66094@isocpp.org>
 <26fe4cb4-98ca-41cc-ac96-5c51851799d1@isocpp.org>
 <fee0a310-5dc5-4421-bf49-bc8fa164fe29@isocpp.org>
 <784ffce8-ace7-449d-a13d-a99d7336117a@isocpp.org>
 <d029c18a-12ee-4a7d-828c-ab1bd07b58c6@isocpp.org>
 <6d0ad98b-87d5-43dd-ac54-2b7d3e03e31b@isocpp.org>
 <bd58ac93-5d20-48e6-93cc-b07a727ce892@isocpp.org>
 <4af80cf7-244c-4137-9133-1a36a209e4ca@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_17683_777117230.1508166662511"
X-Trace: blaine.gmane.org 1508166681 5687 195.159.176.226 (16 Oct 2017 15:11:21 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 16 Oct 2017 15:11:21 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDNMBNHJWIGBBB4YSPHQKGQE225HMOI@isocpp.org Mon Oct 16 17:11:16 2017
Return-path: <std-proposals+bncBDNMBNHJWIGBBB4YSPHQKGQE225HMOI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vk0-f72.google.com ([209.85.213.72])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDNMBNHJWIGBBB4YSPHQKGQE225HMOI@isocpp.org>)
	id 1e472j-0007gA-0p
	for gclcip-std-proposals@m.gmane.org; Mon, 16 Oct 2017 17:11:01 +0200
Original-Received: by mail-vk0-f72.google.com with SMTP id q80sf6134767vka.21
        for <gclcip-std-proposals@m.gmane.org>; Mon, 16 Oct 2017 08:11:08 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=T4aeQqGNCwqBVHFLVmib2zJDeF4u/yydph3R9T2O90Q=;
        b=w1dstU1uRxKCHpBjtO+fequad7JZTTRVq56dAQoWhTzqNwvce/irneLrFl27OXmv+W
         fu2APH/byLcbZyj7krvWJ+wQ7YqKQvZRp6ZeloTv73tUNEzshU5DSYpkf/o6U36Eo2kq
         YKeH2saDwrxBANuAG1q+XMIht81X3Z62ZgnBt6ORFxpfrP5TiI/hhy/egzPhsK5oQsPp
         RzEEn7V6rnFhzJBX1uVB3Q1omBgVkXYWXbbutX2i0G92u2HwdgHVCEzyTkcm5q2j/MZu
         PHITJDzUSaAj9BmvAT/Mf0kwFk65jK9sI++LYm8vAIO3bIF6Qn8FAcPO0FALjUlqI1rG
         ESqg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=T4aeQqGNCwqBVHFLVmib2zJDeF4u/yydph3R9T2O90Q=;
        b=YwXMTY0z/eCzC+LOl7h/ATSio8NoXUvVwKKqvysMRQIZJLany6QVfZaviulp/IJzg+
         ML1FjKI3L+Uvchv8LO18Niw6aUgLAyHmRAFoDka/9Gtqtlwi2o//M0VFhhuHMaabDwVo
         uHX9PyCUnN02wChI/hgrM61844vG1WGU37nUReYHk+nCtKEoUpjXqcaOH7lKK1rIiweu
         aByY8cKJ6yLTB0eZcDnSW0EXulA2z0BY3P47/DP3ASsJrUmLOFMdGhi88/RjGJxbD/EX
         Q/wdLkz9sfuDciKds4LEE5p8GgSZaBm6ox6ruBoI6DvWsBWS+u7Z9b+lE0wX9uafs3xy
         yqCg==
X-Gm-Message-State: AMCzsaXjbkW1vkkD4TJygLCeBpM3nzXhw5dUNw5Q2qQ3cdBJgsyHJKXg
	bCA/MgwTYYDWsktz+ELQiIV8FA==
X-Google-Smtp-Source: AOwi7QDc/bUIX9glZuMZpWy5IebQvEVIxRcXh4RD2L2YUJ/20iSLFkuAHInbirHmrkWyy3vZZkME8w==
X-Received: by 10.176.1.227 with SMTP id 90mr5284379ual.87.1508166668180;
        Mon, 16 Oct 2017 08:11:08 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.21.72 with SMTP id 69ls3368836vkv.17.gmail; Mon, 16 Oct
 2017 08:11:03 -0700 (PDT)
X-Received: by 10.31.50.18 with SMTP id y18mr154190vky.6.1508166663198;
        Mon, 16 Oct 2017 08:11:03 -0700 (PDT)
In-Reply-To: <4af80cf7-244c-4137-9133-1a36a209e4ca@isocpp.org>
X-Original-Sender: wmx16835vv@163.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:34965
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/34965>

------=_Part_17683_777117230.1508166662511
Content-Type: multipart/alternative; 
	boundary="----=_Part_17684_234504532.1508166662513"

------=_Part_17684_234504532.1508166662513
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Monday, October 16, 2017 at 8:26:57 PM UTC+8, Aleksey Loginov wrote:
>
> =D0=BF=D0=BE=D0=BD=D0=B5=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D0=B8=D0=BA, 16 =
=D0=BE=D0=BA=D1=82=D1=8F=D0=B1=D1=80=D1=8F 2017 =D0=B3., 15:08:45 UTC+3 =D0=
=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Mingx=
in Wang=20
> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>>
>> On Monday, October 16, 2017 at 6:55:41 PM UTC+8, Aleksey Loginov wrote:
>>>
>>> Let's look at a more applied example:
>>>
>>> template<size_t Size>=20
>>> struct static_resource : memory_resource { aligned_storage_t<Size>=20
>>> m_data; };
>>>
>>> template<typename MR>
>>> struct my_any;
>>>
>>>
>>> my_any<default_memory_resource> x1;
>>> my_any<static_resource<32>> x2;
>>>
>>> x1 =3D 1;
>>> x2 =3D x1;
>>>
>>> assert(x2 =3D=3D 1);
>>>
>>>
>>> How can you do this without RTTI?
>>>
>>
>> And I don't think `x2` should be copy-assignable from `x1`, if
>>
>>    - `static_resource<32>` is not copy-constructible from=20
>>    `default_memory_resource`, or
>>    - the two memory resources could not be reflexive (being reflexive=20
>>    means, you could allocate some memory from one, and deallocate the me=
mory=20
>>    from another).
>>
>>
>>
> So x1 =3D 1 is valid, but x2 =3D x1 is not valid? Why?
> x2 doesn't deallocates from default_memory_resource. It work only with=20
> static_resource.
>
=20
I am sorry, `x2 =3D x1` *should* be a valid expression. I misjudged the cod=
e=20
and thought it were an assignment between memory resources.

The class template `my_any` may declare any `my_any` types as friend have=
=20
overloads of `operator=3D` for them:

template <class _MR>
friend class my_any;

template <class _MR>
my_any& operator=3D(const my_any<_MR>&);

template <class _MR>
my_any& operator=3D(my_any<_MR>&&);

In order to prove that the class template `my_any` is implementable, I have=
=20
roughly implemented one that supports various of constructors, `operator=3D=
`,=20
`type()` and `get()`. You may use `type()` and `get()` to implement=20
those non-member function templates like `any_cast`.

struct manager_t {
 public:
  template <class T>
  constexpr explicit manager_t(std::in_place_type_t<T>)
      : type(typeid(T)),
        do_copy(do_copy_impl<T>),
        do_move(do_move_impl<T>),
        do_destroy(do_destroy_impl<T>),
        size(sizeof(T)) {}

  constexpr explicit manager_t(std::nullptr_t)
      : type(typeid(void)),
        do_copy(do_copy_null),
        do_move(do_move_null),
        do_destroy(do_destroy_null),
        size(0) {}

  constexpr bool soo_activated() const {
    return size <=3D sizeof(void*);
  }

  template <class MR>
  void copy(void** from, void** to, MR& mr) const {
    if (soo_activated()) {
      do_copy(from, to);
    } else {
      *to =3D mr.allocate(size, ALIGNMENT);
      do_copy(*from, *to);
    }
  }

  void* get(void** data) const {
    return soo_activated() ? data : *data;
  }

  template <class MR>
  void move(void** from, void** to, MR& mr) const {
    if (soo_activated()) {
      do_move(from, to);
    } else {
      *to =3D mr.allocate(size, ALIGNMENT);
      do_move(*from, *to);
    }
  }

  template <class MR>
  void destroy(void** data, MR& mr) const {
    if (soo_activated()) {
      do_destroy(data);
    } else {
      do_destroy(*data);
      mr.deallocate(*data, size, ALIGNMENT);
    }
  }

  const std::type_info& type;

  static inline constexpr std::size_t ALIGNMENT =3D alignof(std::max_align_=
t);

 private:
  void(*do_copy)(void*, void*);
  void(*do_move)(void*, void*);
  void(*do_destroy)(void*);
  std::size_t size;

  template <class T>
  static inline void do_copy_impl(void* from, void* to) {
    new (reinterpret_cast<T*>(to)) T(*reinterpret_cast<const T*>(from));
  }

  template <class T>
  static inline void do_move_impl(void* from, void* to) {
    new (reinterpret_cast<T*>(to))=20
T(std::move(*reinterpret_cast<T*>(from)));
  }

  template <class T>
  static inline void do_destroy_impl(void* data) {
    reinterpret_cast<T*>(data)->~T();
  }

  static inline void do_copy_null(void*, void*) {}
  static inline void do_move_null(void*, void*) {}
  static inline void do_destroy_null(void*) {}
};

template <class T>
inline constexpr manager_t MANAGER{std::in_place_type<T>};

inline constexpr manager_t NULL_MANAGER{nullptr};

template <class MR>
struct memory_resource_user {
  MR mr_;
};

template <class MR>
class my_any;

template <class T>
struct is_my_any : std::false_type {};

template <class MR>
struct is_my_any<my_any<MR>> : std::true_type {};

template <class T>
inline constexpr bool is_my_any_v =3D is_my_any<T>::value;

template <class MR>
class my_any : public memory_resource_user<MR> {
  template <class>
  friend class my_any;

 public:
  template <class T>
  my_any(T&& data) requires !is_my_any_v<std::decay_t<T>>
      { init(std::in_place_type<std::decay_t<T>>, std::forward<T>(data)); }

  template <class T, class... Args>
  explicit my_any(std::in_place_type_t<T>, Args&&... args)
      { init(std::in_place_type<T>, std::forward<Args>(args)...); }

  template<class T, class U, class... Args>
  explicit my_any(std::in_place_type_t<T>, std::initializer_list<U> il,=20
Args&&... args)
      { init(std::in_place_type<T>, il, std::forward<Args>(args)...); }

  constexpr my_any() noexcept { init(); }

  my_any(const my_any& rhs) { copy_init(rhs); }
  my_any(my_any&& rhs) noexcept { move_init(rhs); }

  template <class _MR>
  my_any(const my_any<_MR>& rhs) { copy_init(rhs); }

  template <class _MR>
  my_any(my_any<_MR>&& rhs) noexcept { move_init(rhs); }

  ~my_any() { deinit(); }

  template <class T>
  my_any& operator=3D(T&& data) requires !is_my_any_v<std::decay_t<T>> {
    deinit();
    init(std::in_place_type<std::decay_t<T>>, std::forward<T>(data));
    return *this;
  }

  template <class _MR>
  my_any& operator=3D(const my_any<_MR>& rhs) {
    deinit();
    copy_init(rhs);
    return *this;
  }

  template <class _MR>
  my_any& operator=3D(my_any<_MR>&& rhs) {
    deinit();
    move_init(rhs);
    return *this;
  }

  void* get() const noexcept {
    return manager_->get(&data_);
  }

  bool has_value() const noexcept {
    return manager_ !=3D &NULL_MANAGER;
  }

  const std::type_info& type() const noexcept {
    return manager_->type;
  }

 private:
  void init() { manager_ =3D &NULL_MANAGER; }

  template <class T, class... Args>
  void init(std::in_place_type_t<T>, Args&&... args) requires=20
(MANAGER<T>.soo_activated()) {
    manager_ =3D &MANAGER<T>;
    new (reinterpret_cast<T*>(&data_)) T(std::forward<Args>(args)...);
  }

  template <class T, class... Args>
  void init(std::in_place_type_t<T>, Args&&... args) requires=20
(!MANAGER<T>.soo_activated()) {
    manager_ =3D &MANAGER<T>;
    data_ =3D this->mr_.allocate(sizeof(T), manager_t::ALIGNMENT);
    new (reinterpret_cast<T*>(data_)) T(std::forward<Args>(args)...);
  }

  template <class _MR>
  void copy_init(const my_any<_MR>& rhs) {
    manager_ =3D rhs.manager_;
    manager_->copy(&rhs.data_, &data_, this->mr_);
  }

  template <class _MR>
  void move_init(my_any<_MR>& rhs) {
    manager_ =3D rhs.manager_;
    manager_->move(&rhs.data_, &data_, this->mr_);
  }

  void deinit() {
    manager_->destroy(&data_, this->mr_);
  }

  const manager_t* manager_;
  mutable void* data_;
};

Mingxin Wang

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/7f22751b-91d1-4de4-81d2-421046ceb963%40isocpp.or=
g.

------=_Part_17684_234504532.1508166662513
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, October 16, 2017 at 8:26:57 PM UTC+8, Aleksey L=
oginov wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
=D0=BF=D0=BE=D0=BD=D0=B5=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D0=B8=D0=BA, 16 =D0=
=BE=D0=BA=D1=82=D1=8F=D0=B1=D1=80=D1=8F 2017 =D0=B3., 15:08:45 UTC+3 =D0=BF=
=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Mingxin =
Wang =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr">On Monday, October 16, 2017 at 6:55:41 PM UTC=
+8, Aleksey Loginov wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div>Let&#39;s look at a more applied example:</div><div><br></div=
><div><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,=
187,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><d=
iv><span style=3D"color:#008">template</span><span style=3D"color:#660">&lt=
;</span><span style=3D"color:#000">size_t </span><span style=3D"color:#606"=
>Size</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000=
"> <br></span><span style=3D"color:#008">struct</span><span style=3D"color:=
#000"> static_resource </span><span style=3D"color:#660">:</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:rgb(34,34,34)"><span style=3D=
"color:#000">memory_resource </span><span style=3D"color:#660">{</span><spa=
n style=3D"color:#000"> </span></span><span style=3D"color:rgb(0,0,0);font-=
family:DejaVuSansMono,&quot;DejaVu Sans Mono&quot;,courier,monospace;font-s=
ize:12.8px;white-space:nowrap;background-color:rgb(255,255,255)"><span styl=
e=3D"color:#000">aligned_storage_t</span><span style=3D"color:#660">&lt;</s=
pan></span><span style=3D"color:rgb(102,0,102);font-family:Arial,Helvetica,=
sans-serif">Size</span><span style=3D"color:rgb(0,0,0);font-family:DejaVuSa=
nsMono,&quot;DejaVu Sans Mono&quot;,courier,monospace;font-size:12.8px;whit=
e-space:nowrap;background-color:rgb(255,255,255)"><span style=3D"color:#660=
">&gt;</span></span><span style=3D"font-family:Arial,Helvetica,sans-serif">=
<span style=3D"color:#000"> m_data</span><span style=3D"color:#660">;</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">};</span></s=
pan></div><div><span style=3D"color:#000"><br></span><span style=3D"color:#=
008">template</span><span style=3D"color:#660">&lt;</span><span><font color=
=3D"#000000">typename MR</font></span><span style=3D"color:#660">&gt;</span=
><span style=3D"color:#000"><br></span><span style=3D"color:#008">struct</s=
pan><span style=3D"color:#000">=C2=A0my_any;<br><br><br>my_any&lt;default_<=
/span><span style=3D"color:rgb(0,0,0)">memory_resource</span><span style=3D=
"color:rgb(0,0,0);font-family:Arial,Helvetica,sans-serif"><wbr>&gt; x1;</sp=
an></div><div><span style=3D"color:#000"><span>my_any&lt;</span><span style=
=3D"font-family:Arial,Helvetica,sans-serif">static_resource&lt;32&gt;</span=
><span style=3D"font-family:Arial,Helvetica,sans-serif">&gt; x2;</span><br>=
<br><span style=3D"font-family:Arial,Helvetica,sans-serif">x1 =3D 1;<br>x2 =
=3D x1;<br></span><br>assert(</span><span style=3D"color:rgb(0,0,0);font-fa=
mily:Arial,Helvetica,sans-serif">x2 =3D=3D 1</span><span style=3D"color:rgb=
(0,0,0);font-family:Arial,Helvetica,sans-serif">);</span></div><div><span s=
tyle=3D"color:#000"><br></span></div></code></div><br></div><div>How can yo=
u=C2=A0do this without RTTI?</div></div></blockquote><div><br></div><div>An=
d I don&#39;t think `x2` should be copy-assignable from `x1`, if</div><div>=
<ul><li>`static_resource&lt;32&gt;` is not copy-constructible from `default=
_memory_resource`, or</li><li>the two memory resources could not be reflexi=
ve (being reflexive means, you could allocate some memory from one, and dea=
llocate the memory from another).</li></ul><div><br></div></div></div></blo=
ckquote><div><br></div><div>So x1 =3D 1 is valid, but x2 =3D x1 is not vali=
d? Why?</div><div>x2 doesn&#39;t deallocates from default_memory_resource. =
It work only with static_resource.</div></div></blockquote><div>=C2=A0</div=
><div>I am sorry, `x2 =3D x1` <i>should</i> be a valid expression. I misjud=
ged the code and thought it were an assignment between memory resources.</d=
iv><div><br></div><div>The class template `my_any` may declare any `my_any`=
 types as friend have overloads of `operator=3D` for them:</div><div><br></=
div><div><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250=
, 250); border-color: rgb(187, 187, 187); border-style: solid; border-width=
: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"su=
bprettyprint"><div class=3D"subprettyprint"><div class=3D"subprettyprint">t=
emplate &lt;class _MR&gt;</div><div class=3D"subprettyprint">friend class m=
y_any;</div><div class=3D"subprettyprint"><br></div><div class=3D"subpretty=
print">template &lt;class _MR&gt;</div><div class=3D"subprettyprint">my_any=
&amp; operator=3D(const my_any&lt;_MR&gt;&amp;);</div><div class=3D"subpret=
typrint"><br></div><div class=3D"subprettyprint">template &lt;class _MR&gt;=
</div><div class=3D"subprettyprint">my_any&amp; operator=3D(my_any&lt;_MR&g=
t;&amp;&amp;);</div></div></div></code></div><br>In order to prove that the=
 class template `my_any` is implementable, I have roughly implemented one t=
hat supports various of constructors, `operator=3D`, `type()` and `get()`. =
You may use `type()` and `get()` to implement those=C2=A0non-member functio=
n templates like `any_cast`.</div><div><br></div><div><div class=3D"prettyp=
rint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187,=
 187, 187); border-style: solid; border-width: 1px; word-wrap: break-word;"=
><code class=3D"prettyprint"><div class=3D"subprettyprint"><font color=3D"#=
660066"><div class=3D"subprettyprint">struct manager_t {</div><div class=3D=
"subprettyprint">=C2=A0public:</div><div class=3D"subprettyprint">=C2=A0 te=
mplate &lt;class T&gt;</div><div class=3D"subprettyprint">=C2=A0 constexpr =
explicit manager_t(std::in_place_type_t&lt;T&gt;)</div><div class=3D"subpre=
ttyprint">=C2=A0 =C2=A0 =C2=A0 : type(typeid(T)),</div><div class=3D"subpre=
ttyprint">=C2=A0 =C2=A0 =C2=A0 =C2=A0 do_copy(do_copy_impl&lt;T&gt;),</div>=
<div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 =C2=A0 do_move(do_move_i=
mpl&lt;T&gt;),</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 do_destroy(do_destroy_impl&lt;T&gt;),</div><div class=3D"subprettyprint=
">=C2=A0 =C2=A0 =C2=A0 =C2=A0 size(sizeof(T)) {}</div><div class=3D"subpret=
typrint"><br></div><div class=3D"subprettyprint">=C2=A0 constexpr explicit =
manager_t(std::nullptr_t)</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =
=C2=A0 : type(typeid(void)),</div><div class=3D"subprettyprint">=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 do_copy(do_copy_null),</div><div class=3D"subprettyprint"=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 do_move(do_move_null),</div><div class=3D"subp=
rettyprint">=C2=A0 =C2=A0 =C2=A0 =C2=A0 do_destroy(do_destroy_null),</div><=
div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 =C2=A0 size(0) {}</div><d=
iv class=3D"subprettyprint"><br></div><div class=3D"subprettyprint">=C2=A0 =
constexpr bool soo_activated() const {</div><div class=3D"subprettyprint">=
=C2=A0 =C2=A0 return size &lt;=3D sizeof(void*);</div><div class=3D"subpret=
typrint">=C2=A0 }</div><div class=3D"subprettyprint"><br></div><div class=
=3D"subprettyprint">=C2=A0 template &lt;class MR&gt;</div><div class=3D"sub=
prettyprint">=C2=A0 void copy(void** from, void** to, MR&amp; mr) const {</=
div><div class=3D"subprettyprint">=C2=A0 =C2=A0 if (soo_activated()) {</div=
><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 do_copy(from, to);</div=
><div class=3D"subprettyprint">=C2=A0 =C2=A0 } else {</div><div class=3D"su=
bprettyprint">=C2=A0 =C2=A0 =C2=A0 *to =3D mr.allocate(size, ALIGNMENT);</d=
iv><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 do_copy(*from, *to);<=
/div><div class=3D"subprettyprint">=C2=A0 =C2=A0 }</div><div class=3D"subpr=
ettyprint">=C2=A0 }</div><div class=3D"subprettyprint"><br></div><div class=
=3D"subprettyprint">=C2=A0 void* get(void** data) const {</div><div class=
=3D"subprettyprint">=C2=A0 =C2=A0 return soo_activated() ? data : *data;</d=
iv><div class=3D"subprettyprint">=C2=A0 }</div><div class=3D"subprettyprint=
"><br></div><div class=3D"subprettyprint">=C2=A0 template &lt;class MR&gt;<=
/div><div class=3D"subprettyprint">=C2=A0 void move(void** from, void** to,=
 MR&amp; mr) const {</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 if (s=
oo_activated()) {</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 d=
o_move(from, to);</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 } else {=
</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 *to =3D mr.allocat=
e(size, ALIGNMENT);</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0=
 do_move(*from, *to);</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 }</d=
iv><div class=3D"subprettyprint">=C2=A0 }</div><div class=3D"subprettyprint=
"><br></div><div class=3D"subprettyprint">=C2=A0 template &lt;class MR&gt;<=
/div><div class=3D"subprettyprint">=C2=A0 void destroy(void** data, MR&amp;=
 mr) const {</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 if (soo_activ=
ated()) {</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 do_destro=
y(data);</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 } else {</div><di=
v class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 do_destroy(*data);</div><di=
v class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 mr.deallocate(*data, size, =
ALIGNMENT);</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 }</div><div cl=
ass=3D"subprettyprint">=C2=A0 }</div><div class=3D"subprettyprint"><br></di=
v><div class=3D"subprettyprint">=C2=A0 const std::type_info&amp; type;</div=
><div class=3D"subprettyprint"><br></div><div class=3D"subprettyprint">=C2=
=A0 static inline constexpr std::size_t ALIGNMENT =3D alignof(std::max_alig=
n_t);</div><div class=3D"subprettyprint"><br></div><div class=3D"subprettyp=
rint">=C2=A0private:</div><div class=3D"subprettyprint">=C2=A0 void(*do_cop=
y)(void*, void*);</div><div class=3D"subprettyprint">=C2=A0 void(*do_move)(=
void*, void*);</div><div class=3D"subprettyprint">=C2=A0 void(*do_destroy)(=
void*);</div><div class=3D"subprettyprint">=C2=A0 std::size_t size;</div><d=
iv class=3D"subprettyprint"><br></div><div class=3D"subprettyprint">=C2=A0 =
template &lt;class T&gt;</div><div class=3D"subprettyprint">=C2=A0 static i=
nline void do_copy_impl(void* from, void* to) {</div><div class=3D"subprett=
yprint">=C2=A0 =C2=A0 new (reinterpret_cast&lt;T*&gt;(to)) T(*reinterpret_c=
ast&lt;const T*&gt;(from));</div><div class=3D"subprettyprint">=C2=A0 }</di=
v><div class=3D"subprettyprint"><br></div><div class=3D"subprettyprint">=C2=
=A0 template &lt;class T&gt;</div><div class=3D"subprettyprint">=C2=A0 stat=
ic inline void do_move_impl(void* from, void* to) {</div><div class=3D"subp=
rettyprint">=C2=A0 =C2=A0 new (reinterpret_cast&lt;T*&gt;(to)) T(std::move(=
*reinterpret_cast&lt;T*&gt;(from)));</div><div class=3D"subprettyprint">=C2=
=A0 }</div><div class=3D"subprettyprint"><br></div><div class=3D"subprettyp=
rint">=C2=A0 template &lt;class T&gt;</div><div class=3D"subprettyprint">=
=C2=A0 static inline void do_destroy_impl(void* data) {</div><div class=3D"=
subprettyprint">=C2=A0 =C2=A0 reinterpret_cast&lt;T*&gt;(data)-&gt;~T();</d=
iv><div class=3D"subprettyprint">=C2=A0 }</div><div class=3D"subprettyprint=
"><br></div><div class=3D"subprettyprint">=C2=A0 static inline void do_copy=
_null(void*, void*) {}</div><div class=3D"subprettyprint">=C2=A0 static inl=
ine void do_move_null(void*, void*) {}</div><div class=3D"subprettyprint">=
=C2=A0 static inline void do_destroy_null(void*) {}</div><div class=3D"subp=
rettyprint">};</div><div class=3D"subprettyprint"><br></div><div class=3D"s=
ubprettyprint">template &lt;class T&gt;</div><div class=3D"subprettyprint">=
inline constexpr manager_t MANAGER{std::in_place_type&lt;T&gt;};</div><div =
class=3D"subprettyprint"><br></div><div class=3D"subprettyprint">inline con=
stexpr manager_t NULL_MANAGER{nullptr};</div><div class=3D"subprettyprint">=
<br></div><div class=3D"subprettyprint">template &lt;class MR&gt;</div><div=
 class=3D"subprettyprint">struct memory_resource_user {</div><div class=3D"=
subprettyprint">=C2=A0 MR mr_;</div><div class=3D"subprettyprint">};</div><=
div class=3D"subprettyprint"><br></div><div class=3D"subprettyprint">templa=
te &lt;class MR&gt;</div><div class=3D"subprettyprint">class my_any;</div><=
div class=3D"subprettyprint"><br></div><div class=3D"subprettyprint">templa=
te &lt;class T&gt;</div><div class=3D"subprettyprint">struct is_my_any : st=
d::false_type {};</div><div class=3D"subprettyprint"><br></div><div class=
=3D"subprettyprint">template &lt;class MR&gt;</div><div class=3D"subprettyp=
rint">struct is_my_any&lt;my_any&lt;MR&gt;&gt; : std::true_type {};</div><d=
iv class=3D"subprettyprint"><br></div><div class=3D"subprettyprint">templat=
e &lt;class T&gt;</div><div class=3D"subprettyprint">inline constexpr bool =
is_my_any_v =3D is_my_any&lt;T&gt;::value;</div><div class=3D"subprettyprin=
t"><br></div><div class=3D"subprettyprint">template &lt;class MR&gt;</div><=
div class=3D"subprettyprint">class my_any : public memory_resource_user&lt;=
MR&gt; {</div><div class=3D"subprettyprint">=C2=A0 template &lt;class&gt;</=
div><div class=3D"subprettyprint">=C2=A0 friend class my_any;</div><div cla=
ss=3D"subprettyprint"><br></div><div class=3D"subprettyprint">=C2=A0public:=
</div><div class=3D"subprettyprint">=C2=A0 template &lt;class T&gt;</div><d=
iv class=3D"subprettyprint">=C2=A0 my_any(T&amp;&amp; data) requires !is_my=
_any_v&lt;std::decay_t&lt;T&gt;&gt;</div><div class=3D"subprettyprint">=C2=
=A0 =C2=A0 =C2=A0 { init(std::in_place_type&lt;std::decay_t&lt;T&gt;&gt;, s=
td::forward&lt;T&gt;(data)); }</div><div class=3D"subprettyprint"><br></div=
><div class=3D"subprettyprint">=C2=A0 template &lt;class T, class... Args&g=
t;</div><div class=3D"subprettyprint">=C2=A0 explicit my_any(std::in_place_=
type_t&lt;T&gt;, Args&amp;&amp;... args)</div><div class=3D"subprettyprint"=
>=C2=A0 =C2=A0 =C2=A0 { init(std::in_place_type&lt;T&gt;, std::forward&lt;A=
rgs&gt;(args)...); }</div><div class=3D"subprettyprint"><br></div><div clas=
s=3D"subprettyprint">=C2=A0 template&lt;class T, class U, class... Args&gt;=
</div><div class=3D"subprettyprint">=C2=A0 explicit my_any(std::in_place_ty=
pe_t&lt;T&gt;, std::initializer_list&lt;U&gt; il, Args&amp;&amp;... args)</=
div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 { init(std::in_place=
_type&lt;T&gt;, il, std::forward&lt;Args&gt;(args)...); }</div><div class=
=3D"subprettyprint"><br></div><div class=3D"subprettyprint">=C2=A0 constexp=
r my_any() noexcept { init(); }</div><div class=3D"subprettyprint"><br></di=
v><div class=3D"subprettyprint">=C2=A0 my_any(const my_any&amp; rhs) { copy=
_init(rhs); }</div><div class=3D"subprettyprint">=C2=A0 my_any(my_any&amp;&=
amp; rhs) noexcept { move_init(rhs); }</div><div class=3D"subprettyprint"><=
br></div><div class=3D"subprettyprint">=C2=A0 template &lt;class _MR&gt;</d=
iv><div class=3D"subprettyprint">=C2=A0 my_any(const my_any&lt;_MR&gt;&amp;=
 rhs) { copy_init(rhs); }</div><div class=3D"subprettyprint"><br></div><div=
 class=3D"subprettyprint">=C2=A0 template &lt;class _MR&gt;</div><div class=
=3D"subprettyprint">=C2=A0 my_any(my_any&lt;_MR&gt;&amp;&amp; rhs) noexcept=
 { move_init(rhs); }</div><div class=3D"subprettyprint"><br></div><div clas=
s=3D"subprettyprint">=C2=A0 ~my_any() { deinit(); }</div><div class=3D"subp=
rettyprint"><br></div><div class=3D"subprettyprint">=C2=A0 template &lt;cla=
ss T&gt;</div><div class=3D"subprettyprint">=C2=A0 my_any&amp; operator=3D(=
T&amp;&amp; data) requires !is_my_any_v&lt;std::decay_t&lt;T&gt;&gt; {</div=
><div class=3D"subprettyprint">=C2=A0 =C2=A0 deinit();</div><div class=3D"s=
ubprettyprint">=C2=A0 =C2=A0 init(std::in_place_type&lt;std::decay_t&lt;T&g=
t;&gt;, std::forward&lt;T&gt;(data));</div><div class=3D"subprettyprint">=
=C2=A0 =C2=A0 return *this;</div><div class=3D"subprettyprint">=C2=A0 }</di=
v><div class=3D"subprettyprint"><br></div><div class=3D"subprettyprint">=C2=
=A0 template &lt;class _MR&gt;</div><div class=3D"subprettyprint">=C2=A0 my=
_any&amp; operator=3D(const my_any&lt;_MR&gt;&amp; rhs) {</div><div class=
=3D"subprettyprint">=C2=A0 =C2=A0 deinit();</div><div class=3D"subprettypri=
nt">=C2=A0 =C2=A0 copy_init(rhs);</div><div class=3D"subprettyprint">=C2=A0=
 =C2=A0 return *this;</div><div class=3D"subprettyprint">=C2=A0 }</div><div=
 class=3D"subprettyprint"><br></div><div class=3D"subprettyprint">=C2=A0 te=
mplate &lt;class _MR&gt;</div><div class=3D"subprettyprint">=C2=A0 my_any&a=
mp; operator=3D(my_any&lt;_MR&gt;&amp;&amp; rhs) {</div><div class=3D"subpr=
ettyprint">=C2=A0 =C2=A0 deinit();</div><div class=3D"subprettyprint">=C2=
=A0 =C2=A0 move_init(rhs);</div><div class=3D"subprettyprint">=C2=A0 =C2=A0=
 return *this;</div><div class=3D"subprettyprint">=C2=A0 }</div><div class=
=3D"subprettyprint"><br></div><div class=3D"subprettyprint">=C2=A0 void* ge=
t() const noexcept {</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 retur=
n manager_-&gt;get(&amp;data_);</div><div class=3D"subprettyprint">=C2=A0 }=
</div><div class=3D"subprettyprint"><br></div><div class=3D"subprettyprint"=
>=C2=A0 bool has_value() const noexcept {</div><div class=3D"subprettyprint=
">=C2=A0 =C2=A0 return manager_ !=3D &amp;NULL_MANAGER;</div><div class=3D"=
subprettyprint">=C2=A0 }</div><div class=3D"subprettyprint"><br></div><div =
class=3D"subprettyprint">=C2=A0 const std::type_info&amp; type() const noex=
cept {</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 return manager_-&gt=
;type;</div><div class=3D"subprettyprint">=C2=A0 }</div><div class=3D"subpr=
ettyprint"><br></div><div class=3D"subprettyprint">=C2=A0private:</div><div=
 class=3D"subprettyprint">=C2=A0 void init() { manager_ =3D &amp;NULL_MANAG=
ER; }</div><div class=3D"subprettyprint"><br></div><div class=3D"subprettyp=
rint">=C2=A0 template &lt;class T, class... Args&gt;</div><div class=3D"sub=
prettyprint">=C2=A0 void init(std::in_place_type_t&lt;T&gt;, Args&amp;&amp;=
.... args) requires (MANAGER&lt;T&gt;.soo_activated()) {</div><div class=3D"=
subprettyprint">=C2=A0 =C2=A0 manager_ =3D &amp;MANAGER&lt;T&gt;;</div><div=
 class=3D"subprettyprint">=C2=A0 =C2=A0 new (reinterpret_cast&lt;T*&gt;(&am=
p;data_)) T(std::forward&lt;Args&gt;(args)...);</div><div class=3D"subprett=
yprint">=C2=A0 }</div><div class=3D"subprettyprint"><br></div><div class=3D=
"subprettyprint">=C2=A0 template &lt;class T, class... Args&gt;</div><div c=
lass=3D"subprettyprint">=C2=A0 void init(std::in_place_type_t&lt;T&gt;, Arg=
s&amp;&amp;... args) requires (!MANAGER&lt;T&gt;.soo_activated()) {</div><d=
iv class=3D"subprettyprint">=C2=A0 =C2=A0 manager_ =3D &amp;MANAGER&lt;T&gt=
;;</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 data_ =3D this-&gt;mr_.=
allocate(sizeof(T), manager_t::ALIGNMENT);</div><div class=3D"subprettyprin=
t">=C2=A0 =C2=A0 new (reinterpret_cast&lt;T*&gt;(data_)) T(std::forward&lt;=
Args&gt;(args)...);</div><div class=3D"subprettyprint">=C2=A0 }</div><div c=
lass=3D"subprettyprint"><br></div><div class=3D"subprettyprint">=C2=A0 temp=
late &lt;class _MR&gt;</div><div class=3D"subprettyprint">=C2=A0 void copy_=
init(const my_any&lt;_MR&gt;&amp; rhs) {</div><div class=3D"subprettyprint"=
>=C2=A0 =C2=A0 manager_ =3D rhs.manager_;</div><div class=3D"subprettyprint=
">=C2=A0 =C2=A0 manager_-&gt;copy(&amp;rhs.data_, &amp;data_, this-&gt;mr_)=
;</div><div class=3D"subprettyprint">=C2=A0 }</div><div class=3D"subprettyp=
rint"><br></div><div class=3D"subprettyprint">=C2=A0 template &lt;class _MR=
&gt;</div><div class=3D"subprettyprint">=C2=A0 void move_init(my_any&lt;_MR=
&gt;&amp; rhs) {</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 manager_ =
=3D rhs.manager_;</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 manager_=
-&gt;move(&amp;rhs.data_, &amp;data_, this-&gt;mr_);</div><div class=3D"sub=
prettyprint">=C2=A0 }</div><div class=3D"subprettyprint"><br></div><div cla=
ss=3D"subprettyprint">=C2=A0 void deinit() {</div><div class=3D"subprettypr=
int">=C2=A0 =C2=A0 manager_-&gt;destroy(&amp;data_, this-&gt;mr_);</div><di=
v class=3D"subprettyprint">=C2=A0 }</div><div class=3D"subprettyprint"><br>=
</div><div class=3D"subprettyprint">=C2=A0 const manager_t* manager_;</div>=
<div class=3D"subprettyprint">=C2=A0 mutable void* data_;</div><div class=
=3D"subprettyprint">};</div></font></div></code></div><br>Mingxin Wang</div=
><div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7f22751b-91d1-4de4-81d2-421046ceb963%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7f22751b-91d1-4de4-81d2-421046ceb963=
%40isocpp.org</a>.<br />

------=_Part_17684_234504532.1508166662513--

------=_Part_17683_777117230.1508166662511--

.
