Topic: Dynamic multimethod/type-mapping container
Author: Chris Gary <cgary512@gmail.com>
Date: Wed, 11 Feb 2015 01:54:53 -0800 (PST)
Raw View
------=_Part_273_1222269396.1423648493674
Content-Type: multipart/alternative;
boundary="----=_Part_274_2000655017.1423648493674"
------=_Part_274_2000655017.1423648493674
Content-Type: text/plain; charset=UTF-8
Before I venture to write something up, I wanted to run this by everyone.
I posted this before, but I wasn't happy with the title, formatting, and
some mistakes.
Scenario:
A single, extensible descriptive layer wherein types describe only part of
an object's state.
Several concrete implementations that must extend, at runtime, objects of
descriptive types with relevant state (e.g. A graphics library where "image"
maps to "OpenGLTexture", "Direct3DTexture", or "GDIBitmap" opaquely).
Instances of descriptive types can be re-attached to different
implementations at runtime (e.g. switching renderers without re-loading
active resources from disk). Ergo, straightforward inheritance and
shared_ptr will not work.
A concrete implementation should also provide "best-fit" support for
user-defined types derived from those in the descriptive layer. It should
be possible to alter this support at runtime. Different instances of
implementations (e.g. different graphics context instances) may have
different support depending on plugin/extension selection (or anything,
really).
In other words: Extensible best-fit PIMPL.
Solution:
We need a type map! Not just a static type switch, but an unordered_map
analogue with the semantics of dynamic_cast over the set of target types.
Similar to multimethods, except variations are specified independently and
managed by containers at runtime (this is convenient for dynamic
plugin-based architectures).
Definition Mockup:
// Note: Omitting allocator details and
// assuming polymorphic types for now.
//
template<typename SignatureType>
class caster;
template<
typename ResultType,
typename ArgType, typename ...ArgTypes
>
class caster<ResultType(ArgType, ArgTypes...)>
{
public:
using signature = ResultType(ArgType, ArgTypes...);
template<typename ...OtherArgTypes>
enable_if<is_polymorphically_covariant<
ResultType(OtherArgTypes...),
signature
>, void> erase() // NO ARGUMENTS
{
// Lookup dispatch entry
// Erase if it exists
}
template<typename HandlerType>
enable_if<is_polymorphically_covariant<
signature_of<decay<HandlerType>>, signature
>, void> to(HandlerType &&handler)
{
// Lookup dispatch entry
// If it exists
// Throw bad_argument or something
// Allocate handler node, etc...
}
ResultType operator()(ArgType arg, ArgTypes...args)
{
// This is unambiguous if matches are given
// preference in left-to-right order.
// In the monadic case, this is always unambiguous
// (somewhat like an open dynamic_cast;
// the first match wins).
// The casting logic obviously requires runtime support,
// and is somewhat slow in the variadic case due to
// ABI limitations.
// Lookup best-fitting dispatch entry
// (first by vptr memos, then table lookup)
// If it exists
// Invoke and return result
// Else
// Throw bad_cast
}
template<
typename HandlerType,
typename ...HanderTypes,
typename Enabler = enable_if<
conjunction<
is_polymorphically_covariant<
signature_of<decay<HandlerType>>, signature
>,
is_polymorphically_covariant<
signature_of<decay<HanderTypes>>, signature
>...
>, void>
>
>
caster(HandlerType &&handler, HanderTypes &&...handlers)
{
// Fill table.
// Note: We can do static collision
// checking here!
}
caster &operator = (const caster &other)
{// Copy contents
}
caster &operator = (caster &&other)
{// Clear and move other
}
caster(){}
caster(const caster &other){/*Copy contents*/}
caster(caster &&other){/*Direct move*/}
~caster() noexcept
{}
};
Usage Mockup (monadic example):
class base{public:virtual ~base(){}};
class derived : public base{};
class left_derived : virtual public derived{};
class right_derived : virtual public derived{};
class most_derived : public left_derived, public right_derived{};
caster<int(base &)> c{
[](derived &){ // CASE 1
return 1;
},
[](right_derived &){ // CASE 2
return 3;
},
[](const left_derived &){ // CASE 3
return 2;
}
};
base b;
derived d;
left_derived ld;
right_derived rd;
most_derived md;
c(b); // bad_cast (nothing can accept only a "base &")
c(d); // calls CASE 1
c(ld); // calls CASE 3
c(md); // calls CASE 3 (left_derived matched first during BFS)
c(rd); // calls CASE 2
c.to([](base &){ // CASE 4
return 4;
});
c.to([](const base &){ // bad_argument: Entry already exists
return 4;
});
c(b); // calls CASE 4
c.erase<left_derived &>();
// erases CASE 3
c.erase<const left_derived &>();
// does nothing
// Good? Bad?
// I don't like the idea of iterators here...
promise<base &> p;
// Note: This assumes "then" can accept a
// callable with a simple value-type signature.
//
future<int> f = p.get_future().then(move(c));
p.set_value(md); // calls CASE 2 (right_derived matched)
auto y = f.get(); // y = 3
I have a prototype implementation, but I'm not able to publish the source
at the moment. I will put something together if there is sufficient
interest.
--
---
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 email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_274_2000655017.1423648493674
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Before I venture to write something up, I wanted to run th=
is by everyone.<br><br>I posted this before, but I wasn't happy with the ti=
tle, formatting, and some mistakes.<br><br>Scenario:<br><br>A single, exten=
sible descriptive layer wherein types describe only part of an object's sta=
te.<br><br>Several concrete implementations that must extend, at runtime, o=
bjects of descriptive types with relevant state (e.g. A graphics library wh=
ere "<span style=3D"font-family: courier new,monospace;">image</span>" maps=
to "<span style=3D"font-family: courier new,monospace;">OpenGLTexture</spa=
n>", "<span style=3D"font-family: courier new,monospace;">Direct3DTexture</=
span>", or "<span style=3D"font-family: courier new,monospace;">GDIBitmap</=
span>" opaquely).<br><br>Instances of descriptive types can be re-attached =
to different implementations at runtime (e.g. switching renderers without r=
e-loading active resources from disk). Ergo, straightforward inheritance an=
d <span style=3D"font-family: courier new,monospace;">shared_ptr</span> wil=
l not work.<br><br>A concrete implementation should also provide "best-fit"=
support for user-defined types derived from those in the descriptive layer=
.. It should be possible to alter this support at runtime. Different instanc=
es of implementations (e.g. different graphics context instances) may have =
different support depending on plugin/extension selection (or anything, rea=
lly).<br><br>In other words: Extensible best-fit PIMPL.<br><br>Solution:<br=
><br>We need a type map! Not just a static type switch, but an <span style=
=3D"font-family: courier new,monospace;">unordered_map</span> analogue with=
the semantics of <span style=3D"font-family: courier new,monospace;">dynam=
ic_cast</span> over the set of target types.<br><br>Similar to multimethods=
, except variations are specified independently and managed by containers a=
t runtime (this is convenient for dynamic plugin-based architectures).<br><=
br>Definition Mockup:<br><br><span style=3D"font-family: courier new,monosp=
ace;"> // Note: Omitting allocator details and<br> &=
nbsp; // assuming polymorphic types for now.<br> //=
<br> template<typename SignatureType><br> &nbs=
p; class caster;<br> <br> template<<=
br> typename ResultType,<br> =
; typename ArgType, typename ...ArgType=
s<br> ><br> class caster<ResultTy=
pe(ArgType, ArgTypes...)><br> {<br> =
public:<br> <br> usin=
g signature =3D ResultType(ArgType, ArgTypes...);<br> &nbs=
p; <br> template<t=
ypename ...OtherArgTypes><br> =
enable_if<is_polymorphically_covariant<<br> &n=
bsp; ResultType(OtherArgTypes...),<br>&=
nbsp; signature=
<br> >, void> erase() =
// NO ARGUMENTS<br> =
{<br> // =
Lookup dispatch entry<br> &n=
bsp; // Erase if it exists<br> &nb=
sp; }<br><br> &n=
bsp; template<typename HandlerType><br> =
enable_if<is_polymorphically_covariant<<br> &=
nbsp; signature_of<=
;decay<HandlerType>>, signature<br> &=
nbsp; >, void> to(HandlerType &&handler)<br>  =
; {<br> &n=
bsp; // Lookup dispatch entry<br> =
//=
If it exists<br> &nbs=
p; // Throw bad_argum=
ent or something<br> &=
nbsp; <br>  =
; // Allocate handler node,=
etc...<br> }<br><br> =
ResultType operator()(ArgType arg, ArgTypes.=
...args)<br> {<br> &nbs=
p; // This is unambiguous i=
f matches are given<br> &nbs=
p; // preference in left-to-right order.<br> &=
nbsp; <br>  =
; // In the monadic case, this is alway=
s unambiguous<br> &nbs=
p; // (somewhat like an open dynamic_cast;<br>  =
; // the first match wins).<br><b=
r> // The=
casting logic obviously requires runtime support,<br> &nb=
sp; // and is somewhat slow in th=
e variadic case due to<br> &=
nbsp; // ABI limitations.<br><br> =
// Lookup best-fitting dispatch entry<=
br> // (f=
irst by vptr memos, then table lookup)<br> &nb=
sp; // If it exists<b=
r> &=
nbsp; // Invoke and return result<br>&n=
bsp;  =
; // Else<br> &n=
bsp; // Throw b=
ad_cast<br> }<br><br> =
template<<br> &nbs=
p; typename HandlerType,<br>  =
; typename ...HanderT=
ypes,<br> =
typename Enabler =3D enable_if<<br> =
conjunction<<br>&=
nbsp; &nbs=
p; is_polymorphically_covariant<<br>=
&nb=
sp; signature_o=
f<decay<HandlerType>>, signature<br> &nb=
sp; =
>,<br>  =
; &n=
bsp; is_polymorphically_covariant<<br> &nbs=
p; &=
nbsp; signature_of<decay<HanderTypes>=
;>, signature<br> &=
nbsp; &nbs=
p; >...<br> &=
nbsp; >, void><br> &nb=
sp; ><br> &nb=
sp; ><br> ca=
ster(HandlerType &&handler, HanderTypes &&...handlers)<br>&=
nbsp; {<br> &nbs=
p; // Fill table.<br> =
<br> &nbs=
p; // Note: We can do static collision<=
br> // ch=
ecking here!<br> }<br><br> &=
nbsp; caster &operator =3D (const caster =
&other)<br> {// Copy contents=
<br> }<br>  =
; caster &operator =3D (caster &&other)<br>&n=
bsp; {// Clear and move other<br> =
}<br> &n=
bsp;<br> caster(){}<br> &nbs=
p; caster(const caster &other){/*Copy con=
tents*/}<br> caster(caster &&=
amp;other){/*Direct move*/}<br> ~=
caster() noexcept<br> {}<br> =
; };</span><br> <br>Usage Mockup (monadic example):=
<br><br><span style=3D"font-family: courier new,monospace;"> &nb=
sp; class base{public:virtual ~base(){}};<br> class deriv=
ed : public base{};<br> class left_derived : virtual publ=
ic derived{};<br> class right_derived : virtual public de=
rived{};<br> class most_derived : public left_derived, pu=
blic right_derived{};<br><br> caster<int(base &)&g=
t; c{<br> [](derived &){ =
; // CASE 1<br> =
return 1;<br> &=
nbsp; },<br> &nb=
sp; [](right_derived &){  =
; // CASE 2<br> =
return 3;<br> },<br> =
[](const left_derived &){ &nb=
sp; // CASE 3<br> &nbs=
p; return 2;<br> }<br=
> };<br><br> base b;<br> &nb=
sp; derived d;<br> left_derived ld;<br> =
right_derived rd;<br> most_derived md;<br><br> &nbs=
p; c(b); // bad_cast (nothing can accept only a "ba=
se &")<br> c(d); // calls CASE 1<br=
> c(ld); // calls CASE 3<br>  =
; c(md); // calls CASE 3 (left_derived matched firs=
t during BFS)<br> c(rd); // calls CASE =
2<br> <br> c.to([](base &){ &n=
bsp; // CASE 4<br> return 4;<br>&=
nbsp; });<br> c.to([](const base &){ =
; // bad_argument: Entry already exists<br> &n=
bsp; return 4;<br> });<br><br> &nb=
sp; c(b); // calls CASE 4<br> <br=
> c.erase<left_derived &>();<br> &nb=
sp; // erases CASE 3<br><br> c.erase<const left_derive=
d &>();<br> // does nothing<br> =
// Good? Bad?<br> // I don't like the idea of iterators h=
ere...<br><br> promise<base &> p;<br><br> =
// Note: This assumes "then" can accept a<br>  =
; // callable with a simple value-type signature.<br> //<=
br> future<int> f =3D p.get_future().then(move(c));=
<br><br> p.set_value(md); // calls CASE=
2 (right_derived matched)<br><br> auto y =3D f.get();&nb=
sp; // y =3D 3</span><br><br>I have a prototype implementation,=
but I'm not able to publish the source at the moment. I will put something=
together if there is sufficient interest.<br> </div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_274_2000655017.1423648493674--
------=_Part_273_1222269396.1423648493674--
.
Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Wed, 11 Feb 2015 15:15:56 +0000
Raw View
How would this affect performance?
On 2/11/15, Chris Gary <cgary512@gmail.com> wrote:
> Before I venture to write something up, I wanted to run this by everyone.
>
> I posted this before, but I wasn't happy with the title, formatting, and
> some mistakes.
>
> Scenario:
>
> A single, extensible descriptive layer wherein types describe only part of
> an object's state.
>
> Several concrete implementations that must extend, at runtime, objects of
> descriptive types with relevant state (e.g. A graphics library where "image"
>
> maps to "OpenGLTexture", "Direct3DTexture", or "GDIBitmap" opaquely).
>
> Instances of descriptive types can be re-attached to different
> implementations at runtime (e.g. switching renderers without re-loading
> active resources from disk). Ergo, straightforward inheritance and
> shared_ptr will not work.
>
> A concrete implementation should also provide "best-fit" support for
> user-defined types derived from those in the descriptive layer. It should
> be possible to alter this support at runtime. Different instances of
> implementations (e.g. different graphics context instances) may have
> different support depending on plugin/extension selection (or anything,
> really).
>
> In other words: Extensible best-fit PIMPL.
>
> Solution:
>
> We need a type map! Not just a static type switch, but an unordered_map
> analogue with the semantics of dynamic_cast over the set of target types.
>
> Similar to multimethods, except variations are specified independently and
> managed by containers at runtime (this is convenient for dynamic
> plugin-based architectures).
>
> Definition Mockup:
>
> // Note: Omitting allocator details and
> // assuming polymorphic types for now.
> //
> template<typename SignatureType>
> class caster;
>
> template<
> typename ResultType,
> typename ArgType, typename ...ArgTypes
> >
> class caster<ResultType(ArgType, ArgTypes...)>
> {
> public:
>
> using signature = ResultType(ArgType, ArgTypes...);
>
> template<typename ...OtherArgTypes>
> enable_if<is_polymorphically_covariant<
> ResultType(OtherArgTypes...),
> signature
> >, void> erase() // NO ARGUMENTS
> {
> // Lookup dispatch entry
> // Erase if it exists
> }
>
> template<typename HandlerType>
> enable_if<is_polymorphically_covariant<
> signature_of<decay<HandlerType>>, signature
> >, void> to(HandlerType &&handler)
> {
> // Lookup dispatch entry
> // If it exists
> // Throw bad_argument or something
>
> // Allocate handler node, etc...
> }
>
> ResultType operator()(ArgType arg, ArgTypes...args)
> {
> // This is unambiguous if matches are given
> // preference in left-to-right order.
>
> // In the monadic case, this is always unambiguous
> // (somewhat like an open dynamic_cast;
> // the first match wins).
>
> // The casting logic obviously requires runtime support,
> // and is somewhat slow in the variadic case due to
> // ABI limitations.
>
> // Lookup best-fitting dispatch entry
> // (first by vptr memos, then table lookup)
> // If it exists
> // Invoke and return result
> // Else
> // Throw bad_cast
> }
>
> template<
> typename HandlerType,
> typename ...HanderTypes,
> typename Enabler = enable_if<
> conjunction<
> is_polymorphically_covariant<
> signature_of<decay<HandlerType>>, signature
> >,
> is_polymorphically_covariant<
> signature_of<decay<HanderTypes>>, signature
> >...
> >, void>
> >
> >
> caster(HandlerType &&handler, HanderTypes &&...handlers)
> {
> // Fill table.
>
> // Note: We can do static collision
> // checking here!
> }
>
> caster &operator = (const caster &other)
> {// Copy contents
> }
> caster &operator = (caster &&other)
> {// Clear and move other
> }
>
> caster(){}
> caster(const caster &other){/*Copy contents*/}
> caster(caster &&other){/*Direct move*/}
> ~caster() noexcept
> {}
> };
>
> Usage Mockup (monadic example):
>
> class base{public:virtual ~base(){}};
> class derived : public base{};
> class left_derived : virtual public derived{};
> class right_derived : virtual public derived{};
> class most_derived : public left_derived, public right_derived{};
>
> caster<int(base &)> c{
> [](derived &){ // CASE 1
> return 1;
> },
> [](right_derived &){ // CASE 2
> return 3;
> },
> [](const left_derived &){ // CASE 3
> return 2;
> }
> };
>
> base b;
> derived d;
> left_derived ld;
> right_derived rd;
> most_derived md;
>
> c(b); // bad_cast (nothing can accept only a "base &")
> c(d); // calls CASE 1
> c(ld); // calls CASE 3
> c(md); // calls CASE 3 (left_derived matched first during BFS)
> c(rd); // calls CASE 2
>
> c.to([](base &){ // CASE 4
> return 4;
> });
> c.to([](const base &){ // bad_argument: Entry already exists
> return 4;
> });
>
> c(b); // calls CASE 4
>
> c.erase<left_derived &>();
> // erases CASE 3
>
> c.erase<const left_derived &>();
> // does nothing
> // Good? Bad?
> // I don't like the idea of iterators here...
>
> promise<base &> p;
>
> // Note: This assumes "then" can accept a
> // callable with a simple value-type signature.
> //
> future<int> f = p.get_future().then(move(c));
>
> p.set_value(md); // calls CASE 2 (right_derived matched)
>
> auto y = f.get(); // y = 3
>
> I have a prototype implementation, but I'm not able to publish the source
> at the moment. I will put something together if there is sufficient
> interest.
>
>
> --
>
> ---
> 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
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
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 email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Chris Gary <cgary512@gmail.com>
Date: Wed, 11 Feb 2015 23:19:10 -0800 (PST)
Raw View
------=_Part_1431_1061730067.1423725550901
Content-Type: multipart/alternative;
boundary="----=_Part_1432_1055613146.1423725550901"
------=_Part_1432_1055613146.1423725550901
Content-Type: text/plain; charset=UTF-8
Thanks for your reply.
It's basically an unordered_map<const type_info*,
function<ResultType(ArgType, ArgTypes...)>, except that element lookup
involves a "best-fit" cast of the input over the set of argument types.
So, if the actual type of the argument is already in the map, lookup is
O(1). If the type isn't in the map, the amount of time required for
"no-memo" lookup is proportional to the distance in the inheritance graph
from the actual type to the first type found in the map. Traversal is
performed in breadth-first order.
The primary motivation behind this container is the ability to alter type
mappings at run-time (load a plugin, add relevant types/messages to the
mapping; unload a plugin, remove types/messages from the mapping). So,
there is some overhead.
Here, "best-fit" means to minimize the number of edges traversed in the
inheritance hierarchy. In ambiguous cases select the first match based on
the order of inheritance.
First-fit is already possible though direct iteration over the elements of
such a map, using a separate map to record vptr memos (as in [1]).
The difference in speed would be comparable to using a hash table over a
switch statement: The compiler cannot generate a jump table.
AFAIK, there isn't any way to achieve best-fit mapping of a type over a
dynamic set of types using built-in facilities (except through exception
handling, though that is typically slow and something I consider to be an
abuse of a language feature).
[1]: Open and Efficient Type Switch for C++
On Wednesday, February 11, 2015 at 8:15:58 AM UTC-7, Douglas Boffey wrote:
> How would this affect performance?
--
---
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 email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1432_1055613146.1423725550901
Content-Type: text/html; charset=UTF-8
<div dir="ltr"><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:TrackMoves/>
<w:TrackFormatting/>
<w:PunctuationKerning/>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:DoNotPromoteQF/>
<w:LidThemeOther>EN-US</w:LidThemeOther>
<w:LidThemeAsian>X-NONE</w:LidThemeAsian>
<w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:SplitPgBreakAndParaMark/>
<w:DontVertAlignCellWithSp/>
<w:DontBreakConstrainedForcedTables/>
<w:DontVertAlignInTxbx/>
<w:Word11KerningPairs/>
<w:CachedColBalance/>
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
<m:mathPr>
<m:mathFont m:val="Cambria Math"/>
<m:brkBin m:val="before"/>
<m:brkBinSub m:val="--"/>
<m:smallFrac m:val="off"/>
<m:dispDef/>
<m:lMargin m:val="0"/>
<m:rMargin m:val="0"/>
<m:defJc m:val="centerGroup"/>
<m:wrapIndent m:val="1440"/>
<m:intLim m:val="subSup"/>
<m:naryLim m:val="undOvr"/>
</m:mathPr></w:WordDocument>
</xml><![endif]-->
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman"">Thanks for your reply.</span></p>
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman""> </span></p>
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman"">It's basically an </span><span style="font-size:12.0pt;font-family:"Courier New";mso-fareast-font-family:"Times New Roman"">unordered_map<const
type_info*, function<ResultType(ArgType, ArgTypes...)></span><span style="font-size:12.0pt;font-family:"Times New Roman","serif";mso-fareast-font-family:
"Times New Roman"">, except that element lookup involves a "best-fit"
cast of the input over the set of argument types.</span></p>
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman""> </span></p>
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman"">So, if the actual type of the
argument is already in the map, lookup is O(1). If the type isn't in the map, the
amount of time required for "no-memo" lookup is proportional to the
distance in the inheritance graph from the actual type to the first type found
in the map. Traversal is performed in breadth-first order.<br style="mso-special-character:
line-break">
<br style="mso-special-character:line-break">
</span></p>
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman"">The primary motivation behind this
container is the ability to alter type mappings at run-time (load a plugin, add
relevant types/messages to the mapping; unload a plugin, remove types/messages
from the mapping). So, there is some overhead.</span></p>
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman""> </span></p>
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman"">Here, "best-fit" means to
minimize the number of edges traversed in the inheritance hierarchy. In
ambiguous cases select the first match based on the order of inheritance.</span></p>
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman""> </span></p>
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman"">First-fit is already possible though
direct iteration over the elements of such a map, using a separate map to
record vptr memos (as in [1]).<br>
<br>
The difference in speed would be comparable to using a hash table over a switch
statement: The compiler cannot generate a jump table.<br>
<br>
AFAIK, there isn't any way to achieve best-fit mapping of a type over a dynamic
set of types using built-in facilities (except through exception handling,
though that is typically slow and something I consider to be an abuse of a
language feature).</span></p>
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman""> </span></p>
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman"">[1]: Open and Efficient Type Switch
for C++</span></p>
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman""><br>
<br>
On Wednesday, February 11, 2015 at 8:15:58 AM UTC-7, Douglas Boffey wrote:</span></p>
<p class="MsoNormal" style="margin-bottom:0in;margin-bottom:.0001pt;line-height:
normal"><span style="font-size:12.0pt;font-family:"Times New Roman","serif";
mso-fareast-font-family:"Times New Roman"">> How would this affect performance? </span></p>
<p class="MsoNormal"> </p>
<!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"
DefSemiHidden="true" DefQFormat="false" DefPriority="99"
LatentStyleCount="267">
<w:LsdException Locked="false" Priority="0" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Normal"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="heading 1"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/>
<w:LsdException Locked="false" Priority="39" Name="toc 1"/>
<w:LsdException Locked="false" Priority="39" Name="toc 2"/>
<w:LsdException Locked="false" Priority="39" Name="toc 3"/>
<w:LsdException Locked="false" Priority="39" Name="toc 4"/>
<w:LsdException Locked="false" Priority="39" Name="toc 5"/>
<w:LsdException Locked="false" Priority="39" Name="toc 6"/>
<w:LsdException Locked="false" Priority="39" Name="toc 7"/>
<w:LsdException Locked="false" Priority="39" Name="toc 8"/>
<w:LsdException Locked="false" Priority="39" Name="toc 9"/>
<w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/>
<w:LsdException Locked="false" Priority="10" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Title"/>
<w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/>
<w:LsdException Locked="false" Priority="11" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/>
<w:LsdException Locked="false" Priority="22" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Strong"/>
<w:LsdException Locked="false" Priority="20" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/>
<w:LsdException Locked="false" Priority="59" SemiHidden="false"
UnhideWhenUsed="false" Name="Table Grid"/>
<w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/>
<w:LsdException Locked="false" Priority="1" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 1"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 1"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 1"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/>
<w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/>
<w:LsdException Locked="false" Priority="34" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/>
<w:LsdException Locked="false" Priority="29" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Quote"/>
<w:LsdException Locked="false" Priority="30" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 1"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 1"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 2"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 2"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 2"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 2"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 2"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 3"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 3"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 3"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 3"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 3"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 4"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 4"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 4"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 4"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 4"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 5"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 5"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 5"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 5"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 5"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 6"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 6"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 6"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 6"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 6"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/>
<w:LsdException Locked="false" Priority="19" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/>
<w:LsdException Locked="false" Priority="21" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/>
<w:LsdException Locked="false" Priority="31" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/>
<w:LsdException Locked="false" Priority="32" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/>
<w:LsdException Locked="false" Priority="33" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Book Title"/>
<w:LsdException Locked="false" Priority="37" Name="Bibliography"/>
<w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/>
</w:LatentStyles>
</xml><![endif]--><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin-top:0in;
mso-para-margin-right:0in;
mso-para-margin-bottom:10.0pt;
mso-para-margin-left:0in;
line-height:115%;
mso-pagination:widow-orphan;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:"Times New Roman";
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;}
</style>
<![endif]--></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
------=_Part_1432_1055613146.1423725550901--
------=_Part_1431_1061730067.1423725550901--
.
Author: Chris Gary <cgary512@gmail.com>
Date: Wed, 11 Feb 2015 23:35:27 -0800 (PST)
Raw View
------=_Part_5514_1907046140.1423726527260
Content-Type: multipart/alternative;
boundary="----=_Part_5515_531043505.1423726527260"
------=_Part_5515_531043505.1423726527260
Content-Type: text/plain; charset=UTF-8
I'm very, very scatterbrained today.
By "argument types" I mean the set of types deduced from the signatures of
inserted callables.
The map signature in the example would be closer to unordered_map<type_index,
function<ResultType(ArgType)>>.
I believe there is a benefit to be gained by performing all type
comparisons by address first, then by name. If this optimization were to be
implemented in a space-efficient manner, it would require a new type of
hash table (each bin holds two mappings: ByAddress and ByName).
--
---
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 email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5515_531043505.1423726527260
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I'm very, very scatterbrained today.<br><br>By "argument t=
ypes" I mean the set of types deduced from the signatures of inserted calla=
bles.<br><br>The map signature in the example would be closer to <span styl=
e=3D"font-family: courier new,monospace;">unordered_map<type_index, func=
tion<ResultType(ArgType)>></span>.<br><br>I believe there is a ben=
efit to be gained by performing all type comparisons by address first, then=
by name. If this optimization were to be implemented in a space-efficient =
manner, it would require a new type of hash table (each bin holds two mappi=
ngs: ByAddress and ByName).<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5515_531043505.1423726527260--
------=_Part_5514_1907046140.1423726527260--
.