<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" version="2.0">
  <channel>
    <title>Форум 'C/C++' на RSDN.RU</title>
    <link>http://www.rsdn.ru/Forum/cpp/</link>
    <description>Программирование на C++. No VCL, no MFC, pure C++ only.</description>
    <category>cpp</category>
    <language>ru-ru</language>
    <copyright>Copyright ©, RSDN.ru, 2001-2007</copyright>
    <webMaster>webmaster@rsdn.ru</webMaster>
    <generator>RSDN RSS Generator 1.3</generator>
    <image>
      <url>http://www.rsdn.ru/rsdn.gif</url>
      <title>RSDN.RU</title>
      <link>http://www.rsdn.ru</link>
    </image>
    <lastBuildDate>Thu, 18 Mar 2010 06:00:41 GMT</lastBuildDate>
    <ttl>5</ttl>
	<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/rsdn/cpp" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="rsdn/cpp" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>триангуляция</title>
		<link>http://www.rsdn.ru/Forum/cpp/3739976.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3739976.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3739976.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3739976</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3739976.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3739976</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;Не подскажите, желательно свободной, библиотеки на С++/С содержащей функции триангуляции. Или пакета, с возможностью обращения к нему из C++-программы. &lt;br /&gt;
&lt;br /&gt;
P.S. В пакетах такая возможность есть, например MATLAB функция delaunay() выполняет триангуляцию Делоне.&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/2TAfGcJ13Kw" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Wed, 17 Mar 2010 20:17:49 GMT</pubDate>
		
			<author>barmale-y &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>2</slash:comments>
		
	</item>

	<item>
		<title>Вызов нескольких derived classes из массива</title>
		<link>http://www.rsdn.ru/Forum/cpp/3739265.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3739265.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3739265.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3739265</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3739265.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3739265</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;Добрый!&lt;br /&gt;
Вопрос нуба. &lt;img border='0' width='15' height='15' src='http://www.rsdn.ru/Forum/images/frown.gif' /&gt; В проге решил из структуры сделать объекты, что бы всё было как у взрослых дядек. Но ничего не получилось. Вот упрощенный вариант:&lt;br /&gt;
&lt;table width='96%'&gt;&lt;tr&gt;&lt;td nowrap='nowrap' class='c'&gt;&lt;pre&gt;&lt;span class='kw'&gt;class&lt;/span&gt; A
{
&lt;span class='kw'&gt;public&lt;/span&gt;:
    &lt;span class='kw'&gt;virtual void&lt;/span&gt; VFunc() = 0;
};

&lt;span class='kw'&gt;class&lt;/span&gt; B: &lt;span class='kw'&gt;public&lt;/span&gt; A
{
&lt;span class='kw'&gt;public&lt;/span&gt;:
    &lt;span class='kw'&gt;void&lt;/span&gt; VFunc()
    {
        printf(&lt;span class='str'&gt;"class B\n"&lt;/span&gt;);
    }
};

&lt;span class='kw'&gt;class&lt;/span&gt; C: &lt;span class='kw'&gt;public&lt;/span&gt; A
{
&lt;span class='kw'&gt;public&lt;/span&gt;:
    &lt;span class='kw'&gt;void&lt;/span&gt; VFunc()
    {
        printf(&lt;span class='str'&gt;"class C\n"&lt;/span&gt;);
    }
};

&lt;span class='com'&gt;// здесь можно что-то упростить?&lt;/span&gt;
B b = B();
C c = C();

&lt;span class='kw'&gt;static&lt;/span&gt; A *a[] = {&amp;amp;b, &amp;amp;c, 0 &lt;span class='com'&gt;/*маркер конца списка*/&lt;/span&gt;};
&lt;span class='kw'&gt;static&lt;/span&gt; A *aa[] = {&amp;amp;B(), &amp;amp;C(), 0 &lt;span class='com'&gt;/*маркер конца списка*/&lt;/span&gt;};
&lt;span class='kw'&gt;static&lt;/span&gt; A aaa[] = {B(), C()};

&lt;span class='kw'&gt;int&lt;/span&gt; _tmain(&lt;span class='kw'&gt;int&lt;/span&gt; argc, _TCHAR* argv[])
{
    &lt;span class='com'&gt;// пока работает&lt;/span&gt;
    a[0]-&amp;gt;VFunc();
    a[1]-&amp;gt;VFunc();

    &lt;span class='com'&gt;// коварно вылетает&lt;/span&gt;
    aa[0]-&amp;gt;VFunc();
    aa[1]-&amp;gt;VFunc();

    &lt;span class='com'&gt;// даже не линкуется
    // в реальной проге линкуется, но идет вызов pure virtual&lt;/span&gt;
    aaa[0].VFunc();
    aaa[1].VFunc();

    &lt;span class='kw'&gt;return&lt;/span&gt; 0;
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;
Как сделать правильно?&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/YhM4veF_XC0" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Wed, 17 Mar 2010 13:23:10 GMT</pubDate>
		
			<author>CoolCmd &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>4</slash:comments>
		
	</item>

	<item>
		<title>Транслятор R в C++</title>
		<link>http://www.rsdn.ru/Forum/cpp/3738898.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3738898.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3738898.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3738898</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3738898.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3738898</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;Здравствуйте!&lt;br /&gt;
&lt;br /&gt;
По работе потребовалось портировать программы с &lt;a href="http://en.wikipedia.org/wiki/R_%28programming_language%29" class="m" target="_blank"&gt;R&lt;/a&gt; на С++. Предположительно будет большой объём таких програм, так что я решил написать транслятор. Я примерно знаю как его делать, но хотелось бы узнать у публики, есть ли какие-то готовые инструменты, позволяющие писать такие трансляторы. Если я ошибся форумом, перекиньте куда надо. &lt;br /&gt;
&lt;br /&gt;
Заранее спасибо.&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/x7k1YlZSZwI" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Wed, 17 Mar 2010 10:27:34 GMT</pubDate>
		
			<author>strcpy &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>1</slash:comments>
		
	</item>

	<item>
		<title>STLPort + DigitalMars</title>
		<link>http://www.rsdn.ru/Forum/cpp/3737124.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3737124.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3737124.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3737124</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3737124.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3737124</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;Добрый день!&lt;br /&gt;
&lt;br /&gt;
Пытаюсь собрать STLPort компилятором Digital Mars.&lt;br /&gt;
&lt;br /&gt;
Версия компилятора Digital Mars: 8.51,&lt;br /&gt;
Версия STLPort: 4.5.&lt;br /&gt;
Компилятор и STLPort я скачал с официального сайта. То есть этот STLPort уже адаптирован для компилирования Digital Mars.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Необходимо, чтобы DM собирал программы под DOS, с инструкциями процессора 8088, с моделью памяти Large и эмуляцией операций с плавающей точкой.&lt;/b&gt;&lt;br /&gt;
Без STLPort'a удалось настроить компилятор таким образом.&lt;br /&gt;
&lt;br /&gt;
Привожу пример make файла:&lt;br /&gt;
&lt;br /&gt;
&lt;table width='96%'&gt;&lt;tr&gt;&lt;td nowrap='nowrap' class='c'&gt;&lt;pre&gt;
#    -*- Makefile -*-
.SUFFIXES: .cpp .c .obj .dll .exe .rc .res

CXX=dmc
CC=dmc -cpp
LIB=lib
LINK=dmc
RC=rcc

LIB_BASENAME=stlp45dm_dosl

OBJS = build\c_locale.obj build\c_locale_stub.obj build\codecvt.obj \
    build\collate.obj build\complex.obj build\complex_exp.obj \
    build\complex_io.obj build\complex_io_w.obj build\complex_trig.obj \
    build\ctype.obj build\dll_main.obj \
    build\facets_byname.obj build\fstream.obj build\ios.obj \
    build\iostream.obj build\istream.obj build\locale.obj \
    build\locale_catalog.obj build\locale_impl.obj \
    build\messages.obj build\monetary.obj build\num_get.obj \
    build\num_get_float.obj build\num_put.obj \
    build\num_put_float.obj build\numpunct.obj build\ostream.obj \
    build\sstream.obj build\stdio_streambuf.obj \
    build\streambuf.obj build\string_w.obj build\strstream.obj \
    build\time_facets.obj

BUILD_DIRS=..\lib ..\build \
    ..\build\static ..\build\static\release \
    ..\build\static\debug ..\build\static\stldebug

CXXFLAGS_COMMON = -Ae -Ar &lt;b&gt;-ml -C -S -0 -a2 -c&lt;/b&gt; -D_NOTHREADS &lt;b&gt;-D_STLP_NO_NATIVE_WIDE_FUNCTIONS&lt;/b&gt; -DSTRICT -D__BUILDING_STLPORT -I../stlport

CXXFLAGS_RELEASE_static = $(CXXFLAGS_COMMON) -o+space -Nc

CXXFLAGS_DEBUG_static = $(CXXFLAGS_COMMON) -g -Nc

CXXFLAGS_STLDEBUG_static = $(CXXFLAGS_DEBUG_static) -D_STLP_DEBUG -g -Nc

.cpp{..\build\static\release}.obj:
    $(CXX) -c -o"$@" $(CXXFLAGS_RELEASE_static) "$&amp;lt;"

.cpp{..\build\static\debug}.obj:
    $(CXX) -c -o"$@" $(CXXFLAGS_DEBUG_static) "$&amp;lt;"

.cpp{..\build\static\stldebug}.obj:
    $(CXX) -c -o"$@" $(CXXFLAGS_STLDEBUG_static) "$&amp;lt;"

.c{..\build\static\release}.obj:
    $(CC) -c -o"$@" $(CXXFLAGS_RELEASE_static) "$&amp;lt;"

.c{..\build\static\debug}.obj:
    $(CC) -c -o"$@" $(CXXFLAGS_DEBUG_static) "$&amp;lt;"

.c{..\build\static\stldebug}.obj:
    $(CC) -c -o"$@" $(CXXFLAGS_STLDEBUG_static) "$&amp;lt;"

.rc{..\build}.res:
    $(RC) -32 -o"$@" "$&amp;lt;"

all:    directories all_static

directories:    $(BUILD_DIRS)

$(BUILD_DIRS):
    mkdir $@

all_static:    ..\lib\$(LIB_BASENAME)_static.lib ..\lib\$(LIB_BASENAME)_debug_static.lib ..\lib\$(LIB_BASENAME)_stldebug_static.lib

..\lib\$(LIB_BASENAME)_static.lib:    $(OBJS:build\=..\build\static\release\)
    *$(LIB) -c -n -p256 "$@" "$**"

..\lib\$(LIB_BASENAME)_debug_static.lib:    $(OBJS:build\=..\build\static\debug\)
    *$(LIB) -c -n -p256 "$@" "$**"

..\lib\$(LIB_BASENAME)_stldebug_static.lib:    $(OBJS:build\=..\build\static\stldebug\)
    *$(LIB) -c -n -p256 "$@" "$**"&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
Этот make файл получен из make файла, который поставлялся вместе с STLPort для компилятора Digital Mars. Я просто убрал все упоминания о динамических сборках STLPort и добавил дополнительные ключи компилятора, задающие тип процессора и модель памяти.&lt;br /&gt;
Ключи, которые были добавлены: &lt;b&gt;-ml -C -S -0 -a2 -c&lt;/b&gt;.&lt;br /&gt;
Дефайны, которые были добавлены: &lt;b&gt;_STLP_NO_NATIVE_WIDE_FUNCTIONS&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;STLPort с этим make файлом не собирается!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Если убрать дефайн _STLP_NO_NATIVE_WIDE_FUNCTIONS, вылезут другие ошибки в заголовочных файлах, связанных со строками.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Выдается странная ошибка компилятора о том, что он (компилятор) не может найти прототип функции 'sqrt':&lt;br /&gt;
&lt;br /&gt;
&lt;table width='96%'&gt;&lt;tr&gt;&lt;td nowrap='nowrap' class='c'&gt;&lt;pre&gt;
C:\Development\dm851c\dm\stlport\src&amp;gt;smake -f dm_dos.mak

SMAKE  Program Maintenance Utility (Console) Version 7.50
Copyright (c) 1994-1995 Innovative Data Concepts Incorporated
Copyright (c) 1994-2001 Digital Mars
All Rights Reserved

        dmc -c -o"..\build\static\release\complex.obj" -Ae -Ar -ml -C -S -0 -a2
-c -D_NOTHREADS -D_STLP_NO_NATIVE_WIDE_FUNCTIONS -DSTRICT -D_BUILDING_STLPORT -I
../stlport -o+space -Nc "complex.cpp"
using _STLP_VENDOR_CSTD::sqrt;
                            ^
../stlport\cmath(73) : Error: undefined identifier 'sqrt'
inline float sqrt (float __x)                 { return _STLP_DO_SQRT(float)(__x)
; }
                                                                           ^
../stlport\stl/_cmath.h(163) : Error: function 'sqrt' has no prototype
--- errorlevel 1
SMAKE fatal error: command "dmc" returned with error code 1
Stopping.&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
Примечательно еще и то, что STLPort прекрасно собирается без моих дополнительных ключей компилятора, то есть под Windows, а если установить мои ключи, выдает ошибку про функцию 'sqrt'.&lt;br /&gt;
&lt;br /&gt;
Может нужно установить какой-нибудь хитрый define?&lt;br /&gt;
&lt;br /&gt;
Подскажите пожалуйста.&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/niwIrDGeOP4" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Tue, 16 Mar 2010 07:06:45 GMT</pubDate>
		
			<author>silart &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>3</slash:comments>
		
	</item>

	<item>
		<title>Реальный размер структуры в памяти</title>
		<link>http://www.rsdn.ru/Forum/cpp/3736345.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3736345.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3736345.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3736345</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3736345.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3736345</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;Добрый день!&lt;br /&gt;
&lt;br /&gt;
Вот возник вопрос, как узнать реальный размер заполненной структуры?&lt;br /&gt;
платформа Linux&lt;br /&gt;
&lt;br /&gt;
struct STest&lt;br /&gt;
{&lt;br /&gt;
    STest() : mChar(NULL)&lt;br /&gt;
    {}&lt;br /&gt;
&lt;br /&gt;
    ~STest()&lt;br /&gt;
    {&lt;br /&gt;
        if(mChar)&lt;br /&gt;
            delete [] mChar;&lt;br /&gt;
        mChar = NULL;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    char *mChar;&lt;br /&gt;
    std::string mStr;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    STest tmp;&lt;br /&gt;
&lt;br /&gt;
    tmp.mChar = new char[100];&lt;br /&gt;
    tmp.mStr = "test";&lt;br /&gt;
&lt;br /&gt;
    //  хотелось бы тут получить реальный размер, это грубо говоря 4+4 + 100 + 4 = 112&lt;br /&gt;
    //  грубо говоря потому что std::string("test") явно не 4 байта в памяти занимат&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Спасибо за ответы и за советы )&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/usoDBLdi9Xc" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Mon, 15 Mar 2010 16:04:49 GMT</pubDate>
		
			<author>duncanmclaud &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>3</slash:comments>
		
	</item>

	<item>
		<title>Удаление одинаковых элементов</title>
		<link>http://www.rsdn.ru/Forum/cpp/3735526.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3735526.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3735526.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3735526</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3735526.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3735526</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;можно ли просто и эффективно  с помощью stl удалить из сортированного списка элементы которые&lt;br /&gt;
1) встречаются 2 раза&lt;br /&gt;
2) более одного раза&lt;br /&gt;
3) удалить попарно, тоесть если будет 1,3,3,3 на выходе должно быть 1,3&lt;br /&gt;
&lt;br /&gt;
?&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/q9Cw6uGNQnY" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Mon, 15 Mar 2010 09:32:10 GMT</pubDate>
		
		
			<slash:comments>4</slash:comments>
		
	</item>

	<item>
		<title>Свежие новости с C++0x фронта</title>
		<link>http://www.rsdn.ru/Forum/cpp/3734894.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3734894.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3734894.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3734894</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3734894.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3734894</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;Завершилось собрание коммитета по стандартизации C++ в Пицбурге.  Кое что о нем можно почитать у Саттера: &lt;a href="http://herbsutter.wordpress.com/2010/03/13/trip-report-march-2010-iso-c-standards-meeting/" class="m" target="_blank"&gt;http://herbsutter.wordpress.com/2010/03/13/trip-report-march-2010-iso-c-standards-meeting/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Вкратце, произошли следующие важные вещи:&lt;br /&gt;
* одобрили финальный драфт (FCD), что делает вероятным выпуск стандарта в следующем году.  Те. это будет C++11.&lt;br /&gt;
* export templates выброшена из языка.  Саттеру пришлось целый год лично удовлетворять все прихоти и желания разработчиков EDG пока они не согласились &lt;img border='0' width='15' height='15' src='http://www.rsdn.ru/Forum/images/smile.gif' /&gt;&lt;br /&gt;
* exception specifications deprecated.  А вместо throw(), которого каждый компилятор реализует по-своему, теперь будет noexcept (с булевским параметром &amp;mdash; забавно).&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/HGY7WikhQkQ" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Sun, 14 Mar 2010 18:13:15 GMT</pubDate>
		
			<author>alexeiz &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>5</slash:comments>
		
	</item>

	<item>
		<title>Для чего for_each возвращает копию функтора</title>
		<link>http://www.rsdn.ru/Forum/cpp/3734703.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3734703.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3734703.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3734703</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3734703.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3734703</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;Интересно, для чего for_each возвращает копию функционального объекта. Возможно, есть какие-то приемы, использующие эту фичу?&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/2XoMIH9-OHE" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Sun, 14 Mar 2010 13:38:21 GMT</pubDate>
		
			<author>cpp_beginner &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>1</slash:comments>
		
	</item>

	<item>
		<title>Баг или Фитча?</title>
		<link>http://www.rsdn.ru/Forum/cpp/3733978.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3733978.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3733978.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3733978</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3733978.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3733978</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;Этот код 2005-я студия скомпилила успешно.&lt;br /&gt;
&lt;br /&gt;
&lt;table width='96%'&gt;&lt;tr&gt;&lt;td nowrap='nowrap' class='c'&gt;&lt;pre&gt;
&lt;span class='kw'&gt;template&lt;/span&gt;&amp;lt; &lt;span class='kw'&gt;typename&lt;/span&gt; T=&lt;span class='kw'&gt;int&lt;/span&gt; &amp;gt;
&lt;span class='kw'&gt;struct&lt;/span&gt; S {
    T a;
};


&lt;span class='kw'&gt;typedef&lt;/span&gt; std::vector&amp;lt;S&amp;lt;&amp;gt;&amp;gt;  vS; &lt;span class='com'&gt;//&amp;lt;-- нету пробела &amp;gt; &amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/Gtq8BXdQ_4c" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Sat, 13 Mar 2010 13:13:47 GMT</pubDate>
		
			<author>nen777w &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>2</slash:comments>
		
	</item>

	<item>
		<title>first-class</title>
		<link>http://www.rsdn.ru/Forum/cpp/3733958.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3733958.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3733958.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3733958</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3733958.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3733958</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;Мне задали вопрос по С:&lt;br /&gt;
1 &amp;mdash; Что такое first-class?&lt;br /&gt;
2 &amp;mdash; Являются ли массивы и списки(list.h) first-class?&lt;br /&gt;
&lt;br /&gt;
В гугле я искал и ничего не нашел.&lt;br /&gt;
Спасибо.&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/ZZ0OIkbuKiw" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Sat, 13 Mar 2010 12:05:27 GMT</pubDate>
		
			<author>TheAteist &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>4</slash:comments>
		
	</item>

	<item>
		<title>ошибка на g++</title>
		<link>http://www.rsdn.ru/Forum/cpp/3733886.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3733886.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3733886.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3733886</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3733886.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3733886</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;&lt;table width='96%'&gt;&lt;tr&gt;&lt;td nowrap='nowrap' class='c'&gt;&lt;pre&gt;
&lt;span class='kw'&gt;#define&lt;/span&gt; PR_ADD_FEATURE_P(key, func) \
        m_featureProcessors.insert(FeatureProcessors::value_type(key, \
        boost::bind( boost::mem_fn( &amp;amp;Processor::##func ), &lt;span class='kw'&gt;this&lt;/span&gt;, _1) \
        ) );

        &lt;span class='kw'&gt;void&lt;/span&gt; Processor::setupFeatureProcessors()
        {
                PR_ADD_FEATURE_P(&lt;span class='str'&gt;"DSID"&lt;/span&gt;, processDSID);
        }

&lt;span class='kw'&gt;#undef&lt;/span&gt; PR_ADD_FEATURE_P&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class='q'&gt;&lt;p&gt;error: pasting "::" and "processDSID" does not give a valid preprocessing token&lt;/p&gt;&lt;/blockquote&gt;
&lt;br /&gt;
объясните плиз в чем проблемма...&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/HkA5pwR4gHg" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Sat, 13 Mar 2010 10:05:36 GMT</pubDate>
		
			<author>Denys V. &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>4</slash:comments>
		
	</item>

	<item>
		<title>[Q] index_t, index_cast ?</title>
		<link>http://www.rsdn.ru/Forum/cpp/3733591.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3733591.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3733591.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3733591</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3733591.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3733591</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;Иногда (вплоть до "часто") возникает ситуация, когда смешиваются типы индексов.&lt;br /&gt;
Например, если в интерфейсе int, а в реализации std::vector с size_t.&lt;br /&gt;
Или, что ещё веселее, если в реализации используются ATL::CArray (size_t) и ATL::CSimpleArray (int).&lt;br /&gt;
&lt;br /&gt;
Это порождает такие конструкции&lt;br /&gt;
&lt;table width='96%'&gt;&lt;tr&gt;&lt;td nowrap='nowrap' class='c'&gt;&lt;pre&gt;
&lt;span class='kw'&gt;void&lt;/span&gt; foo(&lt;span class='kw'&gt;int&lt;/span&gt; i)
{
  &lt;span class='com'&gt;//CArray&lt;/span&gt;
  &lt;span class='kw'&gt;if&lt;/span&gt;(i &amp;lt; &lt;b&gt;(&lt;span class='kw'&gt;int&lt;/span&gt;)&lt;/b&gt;arr.GetCount()) {} &lt;span class='com'&gt;// иначе - варнинг о смешивании signed/unsigned&lt;/span&gt;
  &lt;span class='kw'&gt;if&lt;/span&gt;(&lt;b&gt;(size_t)&lt;/b&gt;i &amp;lt; arr.GetCount()) {} &lt;span class='com'&gt;// более опасно, т.к. i&amp;lt;0 более вероятно, чем GetCount()&amp;lt;0 :)&lt;/span&gt;
  &lt;span class='kw'&gt;int&lt;/span&gt; n = &lt;b&gt;(&lt;span class='kw'&gt;int&lt;/span&gt;)&lt;/b&gt;arr.GetCount();
  &lt;span class='kw'&gt;for&lt;/span&gt;(&lt;span class='kw'&gt;int&lt;/span&gt; j=0, c=arr.GetCount(); j!=c; ++j) {} &lt;span class='com'&gt;// волшебным образом, компилятор здесь не выругался&lt;/span&gt;
}
&lt;span class='kw'&gt;void&lt;/span&gt; bar(size_t i)
{
  &lt;span class='com'&gt;//CSimpleArray&lt;/span&gt;
  &lt;span class='kw'&gt;if&lt;/span&gt;(i &amp;lt; &lt;b&gt;(size_t)&lt;/b&gt;arr.GetSize()) {}
  &lt;span class='kw'&gt;if&lt;/span&gt;(&lt;b&gt;(&lt;span class='kw'&gt;int&lt;/span&gt;)&lt;/b&gt;i &amp;lt; arr.GetSize()) {} &lt;span class='com'&gt;// более опасно, т.к. i&amp;gt;MAX_INT более вероятно, чем GetSize()&amp;gt;MAX_INT (понадеемся...)&lt;/span&gt;
  arr.GetAt(&lt;b&gt;(&lt;span class='kw'&gt;int&lt;/span&gt;)&lt;/b&gt;i);
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
Отказаться от int в пользу size_t можно не всегда.&lt;br /&gt;
Во-первых, иногда удобно расширять диапазон индексов в обе стороны: перед-началом и за-концом.&lt;br /&gt;
Во-вторых, сигнальное состояние индекса &amp;mdash; интуитивно понятное -1 против ~0&lt;br /&gt;
В-третьих, legacy, legacy, legacy...&lt;br /&gt;
и т.п.&lt;br /&gt;
&lt;br /&gt;
Конечно, когда заранее известно, что количество элементов способно перевалить за 2Г (а там и за 4Г, если платформа 64-битная) &amp;mdash; нужно использовать правильные типы и вообще быть очень аккуратными.&lt;br /&gt;
Но в остальных ситуациях такой ad-hoc-кастинг&lt;br /&gt;
1) раздражает&lt;br /&gt;
2) вызывает вопросы (откуда куда кастить?)&lt;br /&gt;
3) маскирует проблему&lt;br /&gt;
Маскировка &amp;mdash; ровно та же, что и с C-style-cast: теряется смысл приведения типа в конкретном месте, на фоне похожих по форме, но иных по сути приведений в других местах.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
Решением могло бы стать введение платформенно-комфортного типа.&lt;br /&gt;
Что-то в таком роде&lt;br /&gt;
&lt;table width='96%'&gt;&lt;tr&gt;&lt;td nowrap='nowrap' class='c'&gt;&lt;pre&gt;
&lt;span class='kw'&gt;typedef int&lt;/span&gt; index_t;

&lt;span class='kw'&gt;const&lt;/span&gt; size_t  size_t_npos = ~(size_t)0;
&lt;span class='kw'&gt;const int&lt;/span&gt;     int_npos    = -1;
&lt;span class='kw'&gt;const&lt;/span&gt; index_t npos        = -1;

&lt;span class='kw'&gt;inline&lt;/span&gt; index_t valid_index_cast(&lt;span class='kw'&gt;int&lt;/span&gt;  i) { assert(i&amp;gt;=0); &lt;span class='kw'&gt;return&lt;/span&gt; i; }
&lt;span class='kw'&gt;inline&lt;/span&gt; index_t valid_index_cast(size_t) { assert(i&amp;gt;=0 &amp;amp;&amp;amp; i&amp;lt;INT_MAX); &lt;span class='kw'&gt;return&lt;/span&gt; (index_t)i; }

&lt;span class='kw'&gt;inline&lt;/span&gt; index_t maybe_index_cast(&lt;span class='kw'&gt;int&lt;/span&gt;  i) { assert(i&amp;gt;=-1); &lt;span class='kw'&gt;return&lt;/span&gt; i; }
&lt;span class='kw'&gt;inline&lt;/span&gt; index_t maybe_index_cast(size_t) { assert(i&amp;gt;=0 &amp;amp;&amp;amp; i&amp;lt;INT_MAX || i==size_t_npos); &lt;span class='kw'&gt;return&lt;/span&gt; (index_t)i; }&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;
Тогда код выше превратится в&lt;br /&gt;
&lt;table width='96%'&gt;&lt;tr&gt;&lt;td nowrap='nowrap' class='c'&gt;&lt;pre&gt;
&lt;span class='kw'&gt;void&lt;/span&gt; foo(&lt;span class='kw'&gt;int&lt;/span&gt; _i)
{
  index_t i = maybe_index_cast(_i);
  &lt;span class='com'&gt;//CArray&lt;/span&gt;
  &lt;span class='kw'&gt;if&lt;/span&gt;(i &amp;lt; valid_index_cast(arr.GetCount())) {}
  index_t n = valid_index_cast(arr.GetCount());
  &lt;span class='kw'&gt;for&lt;/span&gt;(index_t j=0, c=arr.GetCount(); j!=c; ++j) {}
}
&lt;span class='kw'&gt;void&lt;/span&gt; bar(size_t _i)
{
  index_t i = maybe_index_cast(_i); &lt;span class='com'&gt;// или valid_index_cast? ага! вопрос себе: нам точно не придёт сигнальное значение?
  //CSimpleArray 
  // - к счастью, он совместим с index_t, поэтому можем проигнорировать кастинг...
  //   хотя, если очень хочется, то valid_index_cast для проверки диапазона - пригодится&lt;/span&gt;
  &lt;span class='kw'&gt;if&lt;/span&gt;(i &amp;lt; arr.GetSize()) {}
  arr.GetAt(i); 
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
Может, чего более симпатичного предложите?&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/cFRE-aDNteQ" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Fri, 12 Mar 2010 19:04:18 GMT</pubDate>
		
			<author>Кодт &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>18</slash:comments>
		
	</item>

	<item>
		<title>RAII + exceptions</title>
		<link>http://www.rsdn.ru/Forum/cpp/3733022.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3733022.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3733022.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3733022</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3733022.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3733022</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;У меня возникло ощущение, что RAII крайне сложно реализуется в С++.&lt;br /&gt;
Обычно применяют такую схему: создается ResourceHolder, который в конструкторе захватывает ресурс, а в деструкторе освобождает его.&lt;br /&gt;
Теперь важный момент: освобождение ресурса может породить исключение (варианты писать в деструкторе BOOL x = CloseHandle(handle); assert(x); считаю некачественным решением), которое уже нельзя просто так кидать из деструктора.&lt;br /&gt;
&lt;br /&gt;
Каким образом вы решаете эту проблему?&lt;br /&gt;
1) это не проблема, assert меня устраивает в деструкторе, глушу исключение&lt;br /&gt;
2) плююсь в лог об ошибке, глушу исключение&lt;br /&gt;
3) закрытие ресурсов проектируется таким образом, чтобы исключений не было&lt;br /&gt;
4) в BOOST_SCOPE_EXIT эта проблема решена, и я его использую без классов ResourceHolder&lt;br /&gt;
5) не стесняюсь использовать std::unhandled_exception в деструкторе и выкидываю исключение из деструктора, если можно&lt;br /&gt;
6) ваш вариант&lt;br /&gt;
&lt;br /&gt;
Спасибо.&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/TYAIvOwShtM" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Fri, 12 Mar 2010 11:35:21 GMT</pubDate>
		
			<author>uzhas &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>110</slash:comments>
		
	</item>

	<item>
		<title>Этюдик с++</title>
		<link>http://www.rsdn.ru/Forum/cpp/3732413.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3732413.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3732413.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3732413</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3732413.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3732413</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;найдите ошибку в коде:&lt;br /&gt;
&lt;table width='96%'&gt;&lt;tr&gt;&lt;td nowrap='nowrap' class='c'&gt;&lt;pre&gt;
&lt;span class='kw'&gt;template&lt;/span&gt;&amp;lt;&lt;span class='kw'&gt;typename&lt;/span&gt; T, intptr_t SIZE&amp;gt;
intptr_t atomic_max_distance_eq(T (&amp;amp;arr)[SIZE])
{
    &lt;span class='kw'&gt;typedef int&lt;/span&gt; assert[__is_class(T)?-1:1];
    intptr_t result = 0;
    &lt;span class='kw'&gt;for&lt;/span&gt; (intptr_t i = SIZE - 1; i &amp;gt; result; i--)
    {
        intptr_t j = -1;
        &lt;span class='kw'&gt;while&lt;/span&gt; (arr[++j] != arr[i]);
        result = max(result, i - j);
    }
    &lt;span class='kw'&gt;return&lt;/span&gt; result;
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;
П.С. Функция работает с массивом базвого типа, и возвращает максимальное расстояние между одинаковыми значениями.&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/esMgUw2qn_k" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Thu, 11 Mar 2010 20:55:13 GMT</pubDate>
		
			<author>Caracrist &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>19</slash:comments>
		
	</item>

	<item>
		<title>Lock-Free FIFO MPMC</title>
		<link>http://www.rsdn.ru/Forum/cpp/3732186.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3732186.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3732186.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3732186</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3732186.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3732186</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;Раз тут объявлен конкурс на lock-free контейнеры, посмотрите, плз.&lt;br /&gt;
&lt;br /&gt;
Используется набор буферов фиксированной длины, связанных в двойной список.&lt;br /&gt;
&lt;br /&gt;
Контейнер используется в проекте, поэтому есть зависимости от других подсистем, не имеющих отношения к самому контейнеру.&lt;br /&gt;
&amp;mdash; _Deconst&amp;lt;T&amp;gt;, снимает константность.&lt;br /&gt;
&amp;mdash; HELPER::Timable объявляет time_t, использование ниже.&lt;br /&gt;
&amp;mdash; HELPER::DataMove::Construct, HELPER::DataMove::Move позволяют использовать move-семантику для конструирования и присваивания объектов. Использует std::swap_move_category для определения возможности использования move-семантики. Прямая проверка наличия swap не используется, т.к. это не всегда выгодно. В общем случае это простое конструирование копии и assigning.&lt;br /&gt;
&amp;mdash; _Constructor::Construct, _Constructor::Destroy вызывают конструктор и деструктор объекта.&lt;br /&gt;
&amp;mdash; SYS::Allocate, SYS::RCIFree выделяет и удаляют память. Используется свой менеджер памяти на основе per-thread букета буферов.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;table width='96%'&gt;&lt;tr&gt;&lt;td nowrap='nowrap' class='c'&gt;&lt;pre&gt;
&lt;span class='kw'&gt;namespace&lt;/span&gt; LF
{        
    &lt;span class='com'&gt;//  односвязный список&lt;/span&gt;
    &lt;span class='kw'&gt;struct&lt;/span&gt; SingleLink
    {
        SingleLink* &lt;span class='kw'&gt;volatile&lt;/span&gt; _lf_next;
    };
    &lt;span class='com'&gt;//  двусвязный список&lt;/span&gt;
    &lt;span class='kw'&gt;struct&lt;/span&gt; DoubleLink : &lt;span class='kw'&gt;public&lt;/span&gt; SingleLink
    {
        DoubleLink* &lt;span class='kw'&gt;volatile&lt;/span&gt; _lf_prev;
    };

    &lt;span class='com'&gt;//  QueueTraits объявляет буфер элементов и использует отдельный массив флагов для
    //  указания состояния слотов буфера. Может использоваться в общем случае.&lt;/span&gt;

    &lt;span class='kw'&gt;template&lt;/span&gt; &amp;lt;&lt;span class='kw'&gt;typename&lt;/span&gt; T, size_t _N = 256&amp;gt;
    &lt;span class='kw'&gt;struct&lt;/span&gt; QueueTraits
    {
        &lt;span class='kw'&gt;typedef typename&lt;/span&gt; _Deconst&amp;lt;T&amp;gt;::Type        data_t;
        
        &lt;span class='kw'&gt;typedef struct&lt;/span&gt; _BANK : 
            &lt;span class='kw'&gt;public&lt;/span&gt; LF::DoubleLink,
            &lt;span class='kw'&gt;public&lt;/span&gt; HELPER::Timable
        {
            BYTE        buffer[&lt;span class='kw'&gt;sizeof&lt;/span&gt;(data_t) * _N];
            &lt;span class='kw'&gt;volatile&lt;/span&gt; BYTE    mask[_N];        

            __forceinline _BANK() &lt;span class='kw'&gt;throw&lt;/span&gt;()
                { memset((BYTE*)mask, 0, &lt;span class='kw'&gt;sizeof&lt;/span&gt;(mask)); }

            __forceinline ~_BANK() &lt;span class='kw'&gt;throw&lt;/span&gt;()
            {
                data_t* objects = &lt;span class='kw'&gt;reinterpret_cast&lt;/span&gt;&amp;lt;data_t*&amp;gt;(buffer);
                &lt;span class='kw'&gt;for&lt;/span&gt; (size_t i = 0; i &amp;lt; _N; ++i)
                    &lt;span class='kw'&gt;if&lt;/span&gt; (QueueTraits::_getMask(&lt;span class='kw'&gt;this&lt;/span&gt;, i))
                        _Constructor::Destroy(&amp;amp;objects[i]);
            }
        } BANK;

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline size_t getSize() &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { &lt;span class='kw'&gt;return&lt;/span&gt; _N; }

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void&lt;/span&gt; Fill(BANK* bank, size_t index, data_t&amp;amp; d) &lt;span class='kw'&gt;throw&lt;/span&gt;()
        {
            data_t* objects = &lt;span class='kw'&gt;reinterpret_cast&lt;/span&gt;&amp;lt;data_t*&amp;gt;(bank-&amp;gt;buffer);
            HELPER::DataMove::Construct(&amp;amp;objects[index], d);  &lt;span class='com'&gt;// new(&amp;amp;objects[index]) data_t(d);
            //  #StoreStore&lt;/span&gt;
            _setMask(bank, index);
        }

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void&lt;/span&gt; Erase(BANK* bank, size_t index, data_t&amp;amp; d) &lt;span class='kw'&gt;throw&lt;/span&gt;()
        {
            _resetMask(bank, index);
            &lt;span class='com'&gt;//  #StoreStore&lt;/span&gt;
            data_t* objects = &lt;span class='kw'&gt;reinterpret_cast&lt;/span&gt;&amp;lt;data_t*&amp;gt;(bank-&amp;gt;buffer);
            HELPER::DataMove::Move(d, objects[index]);  &lt;span class='com'&gt;// d = objects[index];&lt;/span&gt;
            _Constructor::Destroy(&amp;amp;objects[index]);
        }        

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline BOOL IsValid(BANK* bank, size_t index) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { &lt;span class='kw'&gt;return&lt;/span&gt; (0 != _getMask(bank, index)); }

    &lt;span class='kw'&gt;protected&lt;/span&gt;:
        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline BOOL _getMask(BANK* bank, size_t index) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { &lt;span class='kw'&gt;return&lt;/span&gt; (0 != bank-&amp;gt;mask[index]); }
        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void&lt;/span&gt; _setMask(BANK* bank, size_t index) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { bank-&amp;gt;mask[index] = 1; }
        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void&lt;/span&gt; _resetMask(BANK* bank, size_t index) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { bank-&amp;gt;mask[index] = 0; }    
    };

    &lt;span class='com'&gt;//    QueueTraitsDef позволяет использовать "выделенное" значение объекта для 
    //    обозначения "пустого" слота буфера. Позволяет сэкономить на флагах.&lt;/span&gt;
 
    &lt;span class='kw'&gt;template&lt;/span&gt; &amp;lt;&lt;span class='kw'&gt;typename&lt;/span&gt; T, T _Def = T(), size_t _N = 256&amp;gt;
    &lt;span class='kw'&gt;struct&lt;/span&gt; QueueTraitsDef
    {
        &lt;span class='kw'&gt;typedef typename&lt;/span&gt; _Deconst&amp;lt;T&amp;gt;::Type        data_t;
        
        &lt;span class='kw'&gt;typedef struct&lt;/span&gt; _BANK : 
            &lt;span class='kw'&gt;public&lt;/span&gt; _RCI LF::DoubleLink,
            &lt;span class='kw'&gt;public&lt;/span&gt; _RCI HELPER::Timable
        {
            BYTE    buffer[&lt;span class='kw'&gt;sizeof&lt;/span&gt;(data_t) * _N];

            __forceinline _BANK() &lt;span class='kw'&gt;throw&lt;/span&gt;()
            {
                data_t* objects = &lt;span class='kw'&gt;reinterpret_cast&lt;/span&gt;&amp;lt;data_t*&amp;gt;(buffer);
                &lt;span class='kw'&gt;for&lt;/span&gt; (size_t i = 0; i &amp;lt; _N; ++i)
                    _Constructor::Construct(&amp;amp;objects[i], _Def);
            }

            __forceinline ~_BANK() &lt;span class='kw'&gt;throw&lt;/span&gt;()
            {
                data_t* objects = &lt;span class='kw'&gt;reinterpret_cast&lt;/span&gt;&amp;lt;data_t*&amp;gt;(buffer);
                &lt;span class='kw'&gt;for&lt;/span&gt; (size_t i = 0; i &amp;lt; _N; ++i)
                    _Constructor::Destroy(&amp;amp;objects[i]);
            }
        } BANK;

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline size_t getSize() &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { &lt;span class='kw'&gt;return&lt;/span&gt; _N; }

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void&lt;/span&gt; Fill(BANK* bank, size_t index, data_t&amp;amp; d) &lt;span class='kw'&gt;throw&lt;/span&gt;()
        {
            data_t* objects = &lt;span class='kw'&gt;reinterpret_cast&lt;/span&gt;&amp;lt;data_t*&amp;gt;(bank-&amp;gt;buffer);
            HELPER::DataMove::Move(objects[index], d);
        }

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void&lt;/span&gt; Erase(BANK* bank, size_t index, data_t&amp;amp; d) &lt;span class='kw'&gt;throw&lt;/span&gt;()
        {
            data_t* objects = &lt;span class='kw'&gt;reinterpret_cast&lt;/span&gt;&amp;lt;data_t*&amp;gt;(bank-&amp;gt;buffer);
            HELPER::DataMove::Move(d, objects[index]);
            objects[index] = _Def;
        }        

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline BOOL IsValid(BANK* bank, size_t index) &lt;span class='kw'&gt;throw&lt;/span&gt;()
        {
            data_t* objects = &lt;span class='kw'&gt;reinterpret_cast&lt;/span&gt;&amp;lt;data_t*&amp;gt;(bank-&amp;gt;buffer);
            &lt;span class='kw'&gt;return&lt;/span&gt; !(objects[index] == _Def);
        }
    };

    &lt;span class='com'&gt;//    QueueTraitsPtr - частный случай QueueTraitsDef для указателей. 
    //      NULL - "выделенное" значение. Нулевые указатели контейнер хранить не может.&lt;/span&gt;

    &lt;span class='kw'&gt;template&lt;/span&gt; &amp;lt;&lt;span class='kw'&gt;typename&lt;/span&gt; T, size_t _N = 256&amp;gt;
    &lt;span class='kw'&gt;struct&lt;/span&gt; QueueTraitsPtr
    {
        &lt;span class='kw'&gt;typedef typename&lt;/span&gt; _Deconst&amp;lt;T&amp;gt;::Type        data_t;

        &lt;span class='com'&gt;//    boost не используется, поэтому вот такие "самокаты"...&lt;/span&gt;
        &lt;span class='kw'&gt;template&lt;/span&gt; &amp;lt;&lt;span class='kw'&gt;typename&lt;/span&gt; P&amp;gt;
        &lt;span class='kw'&gt;struct&lt;/span&gt; IsPointer
        {
            &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void __fastcall&lt;/span&gt; Initialize(P p[]) &lt;span class='kw'&gt;throw&lt;/span&gt;()
                { }
        };

        &lt;span class='kw'&gt;template&lt;/span&gt; &amp;lt;&lt;span class='kw'&gt;typename&lt;/span&gt; P&amp;gt;
        &lt;span class='kw'&gt;struct&lt;/span&gt; IsPointer&amp;lt;P*&amp;gt;
        {
            &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void __fastcall&lt;/span&gt; Initialize(P* p[]) &lt;span class='kw'&gt;throw&lt;/span&gt;()
                { memset(p, 0, _N * &lt;span class='kw'&gt;sizeof&lt;/span&gt;(P*)); }
        };
        
        &lt;span class='kw'&gt;typedef struct&lt;/span&gt; _BANK : 
            &lt;span class='kw'&gt;public&lt;/span&gt; LF::DoubleLink,
            &lt;span class='kw'&gt;public&lt;/span&gt; HELPER::Timable
        {
            data_t        objects[_N];

            __forceinline _BANK() &lt;span class='kw'&gt;throw&lt;/span&gt;()
                { IsPointer&amp;lt;data_t&amp;gt;::Initialize(objects); }
        } BANK;

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline size_t getSize() &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { &lt;span class='kw'&gt;return&lt;/span&gt; _N; }

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void&lt;/span&gt; Fill(BANK* bank, size_t index, data_t&amp;amp; d) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { bank-&amp;gt;objects[index] = d; }

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void&lt;/span&gt; Erase(BANK* bank, size_t index, data_t&amp;amp; d) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { d = bank-&amp;gt;objects[index]; bank-&amp;gt;objects[index] = NULL; }        

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline BOOL IsValid(BANK* bank, size_t index) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { &lt;span class='kw'&gt;return&lt;/span&gt; !(bank-&amp;gt;objects[index] == NULL); }
    };

    &lt;span class='com'&gt;//    QueueBase, класс очереди.
    //    Примерная схема хранения буферов:
    //
    //                          NULL
    //                          |     &amp;lt;--| data
    //              Reader  -&amp;gt;  PNddddoooooooooooooooo
    //              (Tail)      ||                       ^ _lf_prev
    //                          PNdddddddddddddddddddd   |
    //                          ||                       v _lf_next
    //                          PNdddddddddddddddddddd
    //                          ||
    //              Writer   -&amp;gt; PNoooooooodddddddddddd
    //              (Head)       |        |&amp;lt;-- data
    //                          NULL
    //        &lt;/span&gt;

    &lt;span class='kw'&gt;template&lt;/span&gt; &amp;lt;&lt;span class='kw'&gt;typename&lt;/span&gt; T, &lt;span class='kw'&gt;typename&lt;/span&gt; _Traits = _RCI LF::QueueTraits&amp;lt;T&amp;gt; &amp;gt;
    &lt;span class='kw'&gt;class&lt;/span&gt; QueueBaseT
    {
        &lt;span class='kw'&gt;typedef typename&lt;/span&gt; _Traits::data_t        data_t;
        &lt;span class='kw'&gt;typedef typename&lt;/span&gt; _Traits::BANK            BANK;
        
        &lt;span class='com'&gt;//    Head и Tail содержат пару (указатель на буфер, индекс элемента).
        //    Индекс отсчитывается от _N к нулю. 
        //    Для Head индекс - это индекс последнего добавленного элемента.
        //    Для Tail индекс - это индекс последнего удаленного элемента.
        //    Реализация для 32-битной x86 архитектуры. Для 64 бит немного сложнее.&lt;/span&gt;
&lt;span class='kw'&gt;#ifndef&lt;/span&gt; _WIN64

        &lt;span class='kw'&gt;union&lt;/span&gt; BANK_PTR
        {
            &lt;span class='kw'&gt;volatile __int64&lt;/span&gt;    scalar;
            &lt;span class='kw'&gt;struct&lt;/span&gt;
            {
                &lt;span class='kw'&gt;volatile __int32&lt;/span&gt;    low;    &lt;span class='com'&gt;//    указатель&lt;/span&gt;
                &lt;span class='kw'&gt;volatile __int32&lt;/span&gt;    high;    &lt;span class='com'&gt;//    stamp + index&lt;/span&gt;
            };

            __forceinline &lt;span class='kw'&gt;const&lt;/span&gt; BANK_PTR&amp;amp; &lt;span class='kw'&gt;__fastcall operator&lt;/span&gt; =(&lt;span class='kw'&gt;const volatile&lt;/span&gt; BANK_PTR&amp;amp; p) &lt;span class='kw'&gt;throw&lt;/span&gt;()
                { scalar = p.scalar; &lt;span class='kw'&gt;return&lt;/span&gt; *&lt;span class='kw'&gt;this&lt;/span&gt;; }
            __forceinline BOOL &lt;span class='kw'&gt;__fastcall operator&lt;/span&gt; ==(&lt;span class='kw'&gt;const volatile&lt;/span&gt; BANK_PTR&amp;amp; p) &lt;span class='kw'&gt;const volatile throw&lt;/span&gt;()
                { &lt;span class='kw'&gt;return&lt;/span&gt; (p.scalar == scalar); }
            __forceinline BOOL &lt;span class='kw'&gt;__fastcall operator&lt;/span&gt; ==(&lt;span class='kw'&gt;const&lt;/span&gt; BANK_PTR&amp;amp; p) &lt;span class='kw'&gt;const throw&lt;/span&gt;()
                { &lt;span class='kw'&gt;return&lt;/span&gt; (p.scalar == scalar); }
        };

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void __fastcall&lt;/span&gt; _Init(&lt;span class='kw'&gt;volatile&lt;/span&gt; BANK_PTR&amp;amp; p) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { p.scalar = 0i64; }

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;long __fastcall&lt;/span&gt; _GetIndex(BANK_PTR&amp;amp; p) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { &lt;span class='kw'&gt;return long&lt;/span&gt;(p.high); }
        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void __fastcall&lt;/span&gt; _SetIndex(BANK_PTR&amp;amp; p, &lt;span class='kw'&gt;long&lt;/span&gt; index) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { p.high = &lt;span class='kw'&gt;__int32&lt;/span&gt;(index); }

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline BANK* &lt;span class='kw'&gt;__fastcall&lt;/span&gt; _GetBank(BANK_PTR&amp;amp; p) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { &lt;span class='kw'&gt;return&lt;/span&gt; (BANK*)(ULONG_PTR)p.low; }
        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void __fastcall&lt;/span&gt; _SetBank(BANK_PTR&amp;amp; p, BANK* b) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { p.low = (&lt;span class='kw'&gt;__int32&lt;/span&gt;)(ULONG_PTR)b; }

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline BOOL &lt;span class='kw'&gt;__fastcall&lt;/span&gt; _CAS(&lt;span class='kw'&gt;volatile&lt;/span&gt; BANK_PTR&amp;amp; p, BANK_PTR&amp;amp; pNew, BANK_PTR&amp;amp; pOld) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { &lt;span class='kw'&gt;return&lt;/span&gt; pOld.scalar == _InterlockedCompareExchange64(&amp;amp;p.scalar, pNew.scalar, pOld.scalar); }

        &lt;span class='kw'&gt;static&lt;/span&gt; __forceinline &lt;span class='kw'&gt;void __fastcall&lt;/span&gt; _Read(BANK_PTR&amp;amp; dst, &lt;span class='kw'&gt;volatile&lt;/span&gt; BANK_PTR&amp;amp; src) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { &lt;span class='kw'&gt;do&lt;/span&gt; { dst.high = src.high; dst.low = src.low; } &lt;span class='kw'&gt;while&lt;/span&gt; (dst.high != src.high); }

&lt;span class='kw'&gt;#endif&lt;/span&gt;    &lt;span class='com'&gt;//    _WIN64

        //      В программе есть сервис фоновой "нормализации" приложения, отдельный поток,
        //      который периодически чистит всякий мусор. AutoGarbage - это lock-free
        //      multiple-produces-single-consumer контейнер, "корзина" для хранения мусора, 
        //      которая удаляет объекты (с помощью фонового потока) через определенное время 
        //      (скажем, через минуту после попадания в "корзину"). 
        //      Сам этот контейнер использует интерфейс SingleLink самих буферов, и отдельных
        //      сущностей типа "нода" для них не создает. Для определения последнего
        //      жизненного цикла используется интерфейс Timable.&lt;/span&gt;

        &lt;span class='kw'&gt;typedef&lt;/span&gt; HELPER::AutoGarbage&amp;lt;BANK*, немного всякой bla-bla-bla&amp;gt;    BANKS_AG;
        
        QueueBaseT(&lt;span class='kw'&gt;const&lt;/span&gt; QueueBaseT&amp;amp;);
        &lt;span class='kw'&gt;const&lt;/span&gt; QueueBaseT&amp;amp; &lt;span class='kw'&gt;operator&lt;/span&gt; =(&lt;span class='kw'&gt;const&lt;/span&gt; QueueBaseT&amp;amp;);
    &lt;span class='kw'&gt;public&lt;/span&gt;:
        __forceinline QueueBaseT() &lt;span class='kw'&gt;throw&lt;/span&gt;()
        { 
            _Init(m_head);
            _Init(m_tail);
        }
        __forceinline ~QueueBaseT() &lt;span class='kw'&gt;throw&lt;/span&gt;()
        { 
            BANK_PTR head;

            _Read(head, m_head);

            BANK* banks = _GetBank(head);

            &lt;span class='kw'&gt;if&lt;/span&gt; (NULL != banks)
            {
                &lt;span class='kw'&gt;do&lt;/span&gt;
                {
                    BANK* bank = banks;
                    banks = 
                        &lt;span class='kw'&gt;static_cast&lt;/span&gt;&amp;lt;BANK*&amp;gt;(banks-&amp;gt;_lf_prev);    

                    _Constructor::Destroy(bank);
                    SYS::RCIFree(bank);
                }
                &lt;span class='kw'&gt;while&lt;/span&gt; (NULL != banks);
            }
        }

    &lt;span class='kw'&gt;public&lt;/span&gt;:
        &lt;span class='com'&gt;//  константность не указывается, т.к. используется move-семантика для типов,
        //  для которых это явно разрешено (через std::swap_move_category).&lt;/span&gt;

        __forceinline &lt;span class='kw'&gt;void __fastcall&lt;/span&gt; Push(data_t&amp;amp; d)
        {
            BANK_PTR headOld;
            BANK_PTR headNew;

            &lt;span class='kw'&gt;for&lt;/span&gt; (;;)
            {
                &lt;span class='kw'&gt;long&lt;/span&gt; index;
                
                &lt;span class='kw'&gt;do&lt;/span&gt;
                {
                    _Read(headOld, m_head);    

                    &lt;span class='com'&gt;//    Берем индекс следующего свободного слота. 
                    //    Если новый индекс меньше нуля, весь head-буфер заполнен.&lt;/span&gt;

                    index = _GetIndex(headOld) - 1;
                    &lt;span class='kw'&gt;if&lt;/span&gt; (index &amp;lt; 0)
                        &lt;span class='kw'&gt;break&lt;/span&gt;;

                    _SetBank(headNew, _GetBank(headOld));
                    _SetIndex(headNew, index);
                }
                &lt;span class='kw'&gt;while&lt;/span&gt; (!_CAS(m_head, headNew, headOld));

                &lt;span class='kw'&gt;if&lt;/span&gt; (index &amp;gt;= 0)
                {
                    &lt;span class='com'&gt;//    Кладем элемент в слот и на выход.&lt;/span&gt;
                    _Traits::Fill(_GetBank(headNew), index, d);

                    &lt;span class='kw'&gt;return&lt;/span&gt;;
                }

                BANK* bankNew = &lt;span class='kw'&gt;reinterpret_cast&lt;/span&gt;&amp;lt;BANK*&amp;gt;(SYS::RCIAllocate(&lt;span class='kw'&gt;sizeof&lt;/span&gt;(BANK)));
                &lt;span class='kw'&gt;if&lt;/span&gt; (NULL == bankNew)
                    &lt;span class='kw'&gt;throw&lt;/span&gt; out_of_memory;
                
                _Constructor::Construct(bankNew);
                
                &lt;span class='com'&gt;//    Это guard-объект, который удалит новый созданный буфер, если что...&lt;/span&gt;
                _GUARD_DATA1(guard, bla-bla-bla, BANK*, bankNew);

                _SetBank(headNew, bankNew);
                _SetIndex(headNew, (&lt;span class='kw'&gt;long&lt;/span&gt;)_Traits::getSize());

                BANK* bankOld = _GetBank(headOld);
                bankNew-&amp;gt;_lf_prev = bankOld;
                bankNew-&amp;gt;_lf_next = NULL;

                &lt;span class='com'&gt;//    Используем CAS чтобы вставить новый буфер в head.
                //    Если не получилось, guard удалит созданный буфер.&lt;/span&gt;

                &lt;span class='kw'&gt;if&lt;/span&gt; (_CAS(m_head, headNew, headOld))
                {
                    &lt;span class='com'&gt;//    Если старый буфер существовал, связываем новый к старому.
                    //    Только после этого связывания tail может перейти к новому буферу.
                    //    Если старый буфер не существовал, в контейнере только что создан
                    //    самый первый буфер, в этом случае просто записываем его в tail.&lt;/span&gt;

                    &lt;span class='kw'&gt;if&lt;/span&gt; (NULL != bankOld)
                        bankOld-&amp;gt;_lf_next = bankNew;
                    &lt;span class='kw'&gt;else&lt;/span&gt;
                    {
                        _Init(headOld);

                        _CAS(m_tail, headNew, headOld);
                    }

                    &lt;span class='com'&gt;//    Буфер сохранен, "сбрасываем" guard, чтобы он не удалил его.&lt;/span&gt;
                    guard.Detach();
                }
            }
        }

        __forceinline BOOL Pop(data_t&amp;amp; d) &lt;span class='kw'&gt;throw&lt;/span&gt;()
        {
            BANK_PTR tailOld;
            BANK_PTR tailNew;
            
            &lt;span class='kw'&gt;for&lt;/span&gt; (;;)
            {
                &lt;span class='kw'&gt;long&lt;/span&gt; index;
                
                BANK* bankOld;

                &lt;span class='kw'&gt;do&lt;/span&gt;
                {
                    &lt;span class='kw'&gt;for&lt;/span&gt; (;;)
                    {
                        _Read(tailOld, m_tail);
                        _Read(tailNew, m_head);

                        &lt;span class='com'&gt;//    Если head совпадает c tail - очередь пуста.&lt;/span&gt;

                        &lt;span class='kw'&gt;if&lt;/span&gt; (tailOld == tailNew)
                            &lt;span class='kw'&gt;return&lt;/span&gt; FALSE;
                        
                        &lt;span class='com'&gt;//    Если индекс следующего слота меньше нуля - 
                        //    весь tail-буфер прочитан. Выходим из цикла,
                        //    чтобы удалить его, и перейти к следующему
                        //    буферу по цепочке.&lt;/span&gt;

                        index = _GetIndex(tailOld) - 1;
                        &lt;span class='kw'&gt;if&lt;/span&gt; (index &amp;lt; 0)
                            &lt;span class='kw'&gt;break&lt;/span&gt;;

                        &lt;span class='com'&gt;//    Если элемент в следующем слоте готов для
                        //    считывания, выходим из цикла, чтобы попытаться
                        //    забрать индекс слота себе, и считать элемент.&lt;/span&gt;

                        bankOld = _GetBank(tailOld);
                        &lt;span class='kw'&gt;if&lt;/span&gt; (_Traits::IsValid(bankOld, index))
                            &lt;span class='kw'&gt;break&lt;/span&gt;;    

                        &lt;span class='com'&gt;//    Если выбранный элемент не готов для считывания,
                        //    он либо еще не дописан методом Push (и тогда
                        //    считывать нечего), либо уже считан кем-то другим.
                        //    В последнем случае должен измениться указатель
                        //    на tail, если это так - продолжаем попытки.&lt;/span&gt;

                        _Read(tailNew, m_tail);
                        &lt;span class='kw'&gt;if&lt;/span&gt; (tailNew == tailOld)
                            &lt;span class='kw'&gt;return&lt;/span&gt; FALSE;
                    }

                    &lt;span class='kw'&gt;if&lt;/span&gt; (index &amp;lt; 0)
                        &lt;span class='kw'&gt;break&lt;/span&gt;;

                    _SetBank(tailNew, bankOld);
                    _SetIndex(tailNew, index);
                }
                &lt;span class='kw'&gt;while&lt;/span&gt; (!_CAS(m_tail, tailNew, tailOld));

                &lt;span class='kw'&gt;if&lt;/span&gt; (index &amp;gt;= 0)
                {
                    &lt;span class='com'&gt;//    Элемент готов для считывания и зарезервирован.
                    //    Забираем и уходим.&lt;/span&gt;

                    _Traits::Erase(_GetBank(tailNew), index, d);

                    &lt;span class='kw'&gt;return&lt;/span&gt; TRUE;
                }

                bankOld = _GetBank(tailOld);
                &lt;span class='kw'&gt;if&lt;/span&gt; (NULL == bankOld)
                    &lt;span class='kw'&gt;return&lt;/span&gt; FALSE;        &lt;span class='com'&gt;//    Tail еще не задан, очередь "пуста".
                //    #LoadLoad&lt;/span&gt;
                BANK* bankNew = 
                    &lt;span class='kw'&gt;static_cast&lt;/span&gt;&amp;lt;BANK*&amp;gt;(bankOld-&amp;gt;_lf_next);
                &lt;span class='kw'&gt;if&lt;/span&gt; (NULL == bankNew)
                    &lt;span class='kw'&gt;return&lt;/span&gt; FALSE;        &lt;span class='com'&gt;//    Следующий буфер еще не прилинкован, очередь "пуста".&lt;/span&gt;

                _SetBank(tailNew, bankNew);
                _SetIndex(tailNew, (&lt;span class='kw'&gt;long&lt;/span&gt;)_Traits::getSize());

                &lt;span class='com'&gt;//    Отцепляем "хвост"                                &lt;/span&gt;
                bankNew-&amp;gt;_lf_prev = NULL;

                &lt;span class='com'&gt;//    Если CAS удался - кладем удаленный буфер в "корзину".
                //    При этом, другие потоки могут все еще считывать элементы
                //    из этого буфера, для этого "корзина" гарантирует существование
                //    буфера в течении определенного времени. &lt;/span&gt;

                &lt;span class='kw'&gt;if&lt;/span&gt; (_CAS(m_tail, tailNew, tailOld))
                    m_ag.Push(bankOld);
            }
            &lt;span class='com'&gt;//    unreached code&lt;/span&gt;
            &lt;span class='kw'&gt;return&lt;/span&gt; FALSE;
        }

        __forceinline BOOL IsEmpty() &lt;span class='kw'&gt;const throw&lt;/span&gt;()
            { &lt;span class='kw'&gt;return&lt;/span&gt; (m_head == m_tail); }

                &lt;span class='com'&gt;//  Чистка "корзины", периодически вызывается фоновым потоком.&lt;/span&gt;
        __forceinline size_t Normalize(&lt;span class='kw'&gt;volatile long&lt;/span&gt;* stop) &lt;span class='kw'&gt;throw&lt;/span&gt;()
            { &lt;span class='kw'&gt;return&lt;/span&gt; m_ag.Normalize(stop); }

    &lt;span class='kw'&gt;protected&lt;/span&gt;:
        &lt;span class='kw'&gt;volatile&lt;/span&gt; BANK_PTR    m_head;        
        &lt;span class='kw'&gt;volatile&lt;/span&gt; BANK_PTR    m_tail;        
        BANKS_AG        m_ag;        
    };
};&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/Tg5eie34Fbw" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Thu, 11 Mar 2010 17:35:18 GMT</pubDate>
		
			<author>rus blood &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>6</slash:comments>
		
	</item>

	<item>
		<title>VC8 [BUG], создание экземпляра абстрактрного класса</title>
		<link>http://www.rsdn.ru/Forum/cpp/3731993.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3731993.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3731993.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3731993</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3731993.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3731993</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;VS2005, разрешает создавать экземпляр абстрактного класса, в качестве временного обьекта.&lt;br /&gt;
&lt;br /&gt;
В чатности:&lt;br /&gt;
&lt;table width='96%'&gt;&lt;tr&gt;&lt;td nowrap='nowrap' class='c'&gt;&lt;pre&gt;
&lt;span class='kw'&gt;class&lt;/span&gt; AbstractClass
{
&lt;span class='kw'&gt;public&lt;/span&gt;:
    AbstractClass(&lt;span class='kw'&gt;int&lt;/span&gt; id)
    {
    }
    &lt;span class='kw'&gt;virtual void&lt;/span&gt; foo()=0;
};

&lt;span class='kw'&gt;void&lt;/span&gt; function (&lt;span class='kw'&gt;const&lt;/span&gt; AbstractClass&amp;amp; aaa)
{
}

&lt;span class='kw'&gt;int&lt;/span&gt; main()
{
    &lt;span class='kw'&gt;int&lt;/span&gt; id=0;
    function(id);
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;
компилируется без ошибок.&lt;br /&gt;
&lt;br /&gt;
P.S.&lt;br /&gt;
Comeau C/C++ и MinGW выдают ошибку. error: cannot allocate an object of type `const AbstractClass'&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/P4oW-V3APqc" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Thu, 11 Mar 2010 15:24:22 GMT</pubDate>
		
			<author>Chorkov &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>4</slash:comments>
		
	</item>

	<item>
		<title>set из stl</title>
		<link>http://www.rsdn.ru/Forum/cpp/3731706.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3731706.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3731706.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3731706</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3731706.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3731706</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;необходимо описать структуру set из stl на С&lt;br /&gt;
помогите кто чем может.))&lt;br /&gt;
 &lt;br /&gt;
с контейнерами знаком лишь в общих чертах: &lt;br /&gt;
если можно еще и по ним что-нибудь посоветуйте почитать&lt;br /&gt;
&lt;br /&gt;
заранее спасибо)&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/DsVgMztGKEw" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Thu, 11 Mar 2010 12:21:16 GMT</pubDate>
		
			<author>zorata &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>3</slash:comments>
		
	</item>

	<item>
		<title>template&lt;typename ValueT, ValueT (*)() func&gt;</title>
		<link>http://www.rsdn.ru/Forum/cpp/3731431.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3731431.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3731431.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3731431</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3731431.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3731431</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;subj.&lt;br /&gt;
Идея понятна? как теперь заставить это компилироваться?&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/RAbHkGTEjHk" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Thu, 11 Mar 2010 08:22:02 GMT</pubDate>
		
			<author>Caracrist &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>2</slash:comments>
		
	</item>

	<item>
		<title>О lock-free алгоритмах (+бонус)</title>
		<link>http://www.rsdn.ru/Forum/cpp/3730905.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3730905.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3730905.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3730905</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3730905.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3730905</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;[пост получился достаточно длинный, поэтому сразу скажу о бонусе — это простой и эффективный алгоритм очереди на основе буфера фиксированного размера — нетерпеливые могут сразу перемещаться к концу поста &lt;img border='0' width='15' height='15' src='http://www.rsdn.ru/Forum/images/smile.gif' /&gt; ]&lt;br /&gt;
&lt;br /&gt;
Последние дни на RSDN шла своего рода распределенная игра по написанию lock-free контейнеров. Вначале vf запостил lock-free стек для .Net:&lt;br /&gt;
&lt;a href="http://www.rsdn.ru/forum/dotnet/3719883.aspx" title="Lock-free array-based stack" class=" tips m" rel="#m3719883" target="_blank"&gt;http://www.rsdn.ru/forum/dotnet/3719883.aspx&lt;div class="tooltip" id="m3719883"&gt;Автор: vf&lt;br /&gt;Дата: 27.02 19:07&lt;/div&gt;&lt;/a&gt;&lt;br /&gt;
Я указал, что в стеке содержится достаточно изощренная ошибка:&lt;br /&gt;
&lt;a href="http://www.rsdn.ru/forum/dotnet/3721436.1.aspx" title="Lock-free array-based stack" class=" tips m" rel="#m3721436" target="_blank"&gt;http://www.rsdn.ru/forum/dotnet/3721436.1.aspx&lt;div class="tooltip" id="m3721436"&gt;Автор: remark&lt;br /&gt;Дата: 01.03 16:06&lt;/div&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Потом Caracrist запостил lock-free очередь для С++:&lt;br /&gt;
&lt;a href="http://www.rsdn.ru/forum/src/3725942.1.aspx" title="Interlocked Circle Buffer" class=" tips m" rel="#m3725942" target="_blank"&gt;http://www.rsdn.ru/forum/src/3725942.1.aspx&lt;div class="tooltip" id="m3725942"&gt;Автор: Caracrist&lt;br /&gt;Дата: 05.03 15:05&lt;/div&gt;&lt;/a&gt;&lt;br /&gt;
Я указал на ряд ошибок:&lt;br /&gt;
&lt;a href="http://www.rsdn.ru/forum/src/3726327.1.aspx" title="Interlocked Circle Buffer" class=" tips m" rel="#m3726327" target="_blank"&gt;http://www.rsdn.ru/forum/src/3726327.1.aspx&lt;div class="tooltip" id="m3726327"&gt;Автор: remark&lt;br /&gt;Дата: 05.03 20:15&lt;/div&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Потом дали ссылку на блог некого товарища из Яндекса с описанием lock-free стека для С++:&lt;br /&gt;
&lt;a href="http://users.livejournal.com/_foreseer/34284.html" class="m" target="_blank"&gt;http://users.livejournal.com/_foreseer/34284.html&lt;/a&gt;&lt;br /&gt;
Я тоже указал на ошибку:&lt;br /&gt;
&lt;a href="http://www.rsdn.ru/forum/dotnet/3721636.1.aspx" title="Lock-free array-based stack" class=" tips m" rel="#m3721636" target="_blank"&gt;http://www.rsdn.ru/forum/dotnet/3721636.1.aspx&lt;div class="tooltip" id="m3721636"&gt;Автор: remark&lt;br /&gt;Дата: 01.03 18:16&lt;/div&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
К чему я это? Что не надо писать lock-free контейнеры? Это смотрите сами, мне всё равно. Это пусть говорят другие, те которые сами не умеют писать lock-free алгоритмы &lt;img border='0' width='15' height='15' src='http://www.rsdn.ru/Forum/images/smile.gif' /&gt; В целом lock-free алгоритмы писать вполне реалистично, единственное надо немного сноровки, ревью коллег, и соответствующие инструменты.&lt;br /&gt;
Кстати, по поводу инструментов, тут я не могу не упомянуть в качестве рекламы свой &lt;a href="http://groups.google.com/group/relacy" class="m" target="_blank"&gt;Relacy Race Detector&lt;/a&gt;. Если последние 2 ошибки удалось найти при просмотре кода, то первую смог вскрыть только &lt;a href="http://groups.google.com/group/relacy" class="m" target="_blank"&gt;Relacy Race Detector&lt;/a&gt; (кстати, если кто следит за такими тулзами, то &lt;a href="http://research.microsoft.com/en-us/projects/chess/" class="m" target="_blank"&gt;CHESS от Microsoft&lt;/a&gt; не смог её найти — ограничение планировщика потоков).&lt;br /&gt;
&lt;br /&gt;
Я должен отметить, что Caracrist в итоге запостил корректный алгоритм очереди, ну по-крайней мере я не вижу ошибок:&lt;br /&gt;
&lt;a href="http://www.rsdn.ru/forum/src/3727286.1.aspx" title="Fixed: Interlocked Circle Buffer" class=" tips m" rel="#m3727286" target="_blank"&gt;http://www.rsdn.ru/forum/src/3727286.1.aspx&lt;div class="tooltip" id="m3727286"&gt;Автор: Caracrist&lt;br /&gt;Дата: 07.03 12:42&lt;/div&gt;&lt;/a&gt;&lt;br /&gt;
Однако алгоритм получился достаточно сложный — 6 независимых переменных состояния, плюс достаточно не эффективный — 6 Interlocked инструкций на операцию. Для сравнения аналогичный алгоритм с применением спин-мьютекса будет исполнять по 1 Interlocked инструкций на операцию, и соотв. Будет в 6 раз быстрее в случае низкой конкуренции.&lt;br /&gt;
&lt;br /&gt;
В чём сложность создания таких алгоритмов? В том, что последовательность атомарных операций сама по себе не является атомарной операций, это по-прежнему разрозненная последовательность (в отличие от алгоритмов, основанных на мьютексах). Наибольшую сложность представляют промежуточные состояния структуры данных, которые возникают в процессе выполнения последовательности. Каждое такое состояние должно быть полностью целостным. Целостным в том плане, что если придёт другой поток, то он должен посмотреть на структуру; определить, что это за состояние; понять, что ему делать дальше; и при этом не порушить планы первого потока. Даже хуже — прерываний потоков может быть несколько, т.е. первый поток перевёл структуру в какое промежуточное состояние; потом пришёл второй поток, и тоже выполнил часть операции; потом пришёл третий поток, выполнил ещё несколько незаконченных действий, и т.д. И после всего этого структура всё ещё должна оставаться в понятном консистентном состоянии.&lt;br /&gt;
В идеале поток целиком выполняет операцию за одну атомарную операцию, т.е. считывает состояние структуры, проверяет его, вычисляет новое состояние, и пытается атомарно перевести структуру из исходного состояния в новое с помощью CAS (InterlockedCompareExchange). Так работает известный алгоритм lock-free стека:&lt;br /&gt;
&lt;a href="http://www.rsdn.ru/forum/dotnet/3721740.1.aspx" title="Lock-free array-based stack" class=" tips m" rel="#m3721740" target="_blank"&gt;http://www.rsdn.ru/forum/dotnet/3721740.1.aspx&lt;div class="tooltip" id="m3721740"&gt;Автор: remark&lt;br /&gt;Дата: 01.03 19:41&lt;/div&gt;&lt;/a&gt;&lt;br /&gt;
В таком алгоритме нет промежуточных (читай — потенциально проблематичных) состояний, структура либо не модифицирована вообще, либо операция полностью выполнена.&lt;br /&gt;
Однако это применимо только для простейших случаев, в более сложных случаях невозможно выполнить операцию за одну атомарную операцию — как в случае с очередью на основе фиксированного буфера, тут надо и записать данные и сместить позицию записи.&lt;br /&gt;
&lt;br /&gt;
Кстати, к вопросу о сложных операциях с множеством промежуточных состояний, есть такая интересная презентация Cliff Click (сейчас он работает в Azul Systems, ранее в Sun – и там и там он был ключевой фигурой в разработке JVM) о реализации полностью lock-free хэш-мап (код доступен в сети):&lt;br /&gt;
&lt;a href="http://www.azulsystems.com/events/javaone_2007/2007_LockFreeHash.pdf" class="m" target="_blank"&gt;http://www.azulsystems.com/events/javaone_2007/2007_LockFreeHash.pdf&lt;/a&gt;&lt;br /&gt;
Представьте себе хэш-мап, в котором несколько потоков одновременно добавляют один и тот же элемент, несколько пытаются его считать, несколько удалить, и плюс одновременно с этим происходит увеличение размера таблицы. Каково? Клиф подошёл к вопросу фундаментально — он нарисовал в явном виде стейт-машину для ячейки таблицы; для каждого состояния описал как его можно определить (в смысле понять, что ячейка сейчас находится именно в этом состоянии); для каждой пары (состояние, тип операции (чтение, добавление, удаление)) описал, что потоку делать дальше; и потом реализовал все переходы между состояниями с помощью атомарных CAS.&lt;br /&gt;
Это если поверхностно, в реальности там много деталей и есть некоторые негативные моменты, которые он сам же внёс дабы реализовать хэш полностью без блокировок. Например, элементы никогда полностью не удаляются из таблицы, они просто помечаются как удалённые. Как следствие, даже если количество элементов в таблице остаётся постоянным, но происходят вставки и удаления элементов, ему приходится делать периодические фиктивные ресайзы таблицы, что бы «подчистить мусор». Ещё там могут быть проблематичными рекурсивные ресайзы таблицы... ну ладно, это я уже удаляюсь от темы.&lt;br /&gt;
&lt;br /&gt;
Теперь обещанный бонус &amp;mdash; алгоритм bounded multi-producer/multi-consumer очереди без блокировок. Контейнер не использует динамического выделения/управления памятью в процессе работы (за исключением изначального выделения фиксированного буфера). &lt;br /&gt;
Каждая операция содержит всего по 1 Interlocked инструкции, и как следствие будет достаточно быстрой.&lt;br /&gt;
Тут ситуация существенно попроще, чем у Клифа с его таблицей (и это к лучшему). Каждая операция (чтение/запись) состоит из 2 атомарных действий. (1) поток проверяет и резервирует элемент для чтения/записи, и (2) после выполнения фактического чтения/записи, помечает элемент как доступный для следующей операции (записи/чтения соответственно). Тут есть только одно промежуточное состояние — между (1) и (2) — которое должным образом обрабатывается.&lt;br /&gt;
Далее собственно код с комментариями:&lt;br /&gt;
&lt;table width='96%'&gt;&lt;tr&gt;&lt;td nowrap='nowrap' class='c'&gt;&lt;pre&gt;
&lt;span class='kw'&gt;template&lt;/span&gt;&amp;lt;&lt;span class='kw'&gt;typename&lt;/span&gt; T&amp;gt;
&lt;span class='kw'&gt;class&lt;/span&gt; mpmc_bounded_queue
{
&lt;span class='kw'&gt;public&lt;/span&gt;:
    mpmc_bounded_queue(size_t buffer_size)
        : buffer_(&lt;span class='kw'&gt;new&lt;/span&gt; cell_t [buffer_size])
        , buffer_mask_(buffer_size - 1)
    {
        &lt;span class='kw'&gt;typedef char&lt;/span&gt; assert_nothrow [__has_nothrow_assign(T) || __has_trivial_assign(T) || !__is_class(T) ? 1 : -1];
        assert((buffer_size &amp;gt;= 2) &amp;amp;&amp;amp; ((buffer_size &amp;amp; (buffer_size - 1)) == 0));
        &lt;span class='kw'&gt;for&lt;/span&gt; (size_t i = 0; i != buffer_size; i += 1)
            buffer_[i].sequence_.store(i, std::memory_order_relaxed);
        enqueue_pos_.store(0, std::memory_order_relaxed);
        dequeue_pos_.store(0, std::memory_order_relaxed);
    }

    ~mpmc_bounded_queue()
    {
        &lt;span class='kw'&gt;delete&lt;/span&gt; [] buffer_;
    }

    &lt;span class='kw'&gt;bool&lt;/span&gt; enqueue(T &lt;span class='kw'&gt;const&lt;/span&gt;&amp;amp; data)
    {
        cell_t* cell;
        &lt;span class='com'&gt;// загружаем текущую позицию для добавления в очередь&lt;/span&gt;
        size_t pos = enqueue_pos_.load(std::memory_order_relaxed);
        &lt;span class='kw'&gt;for&lt;/span&gt; (;;)
        {
            &lt;span class='com'&gt;// находим текущий элемент&lt;/span&gt;
            cell = &amp;amp;buffer_[pos &amp;amp; buffer_mask_];
            &lt;span class='com'&gt;// загружаем статус (sequence) текущего элемента&lt;/span&gt;
            size_t seq = cell-&amp;gt;sequence_.load(std::memory_order_acquire);
            intptr_t dif = (intptr_t)seq - (intptr_t)pos;
            &lt;span class='com'&gt;// элемент готов для записи&lt;/span&gt;
            &lt;span class='kw'&gt;if&lt;/span&gt; (dif == 0)
            {
                &lt;span class='com'&gt;// пытаемся сдвинуть позицию для добавления&lt;/span&gt;
                &lt;span class='kw'&gt;if&lt;/span&gt; (enqueue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed))
                    &lt;span class='kw'&gt;break&lt;/span&gt;;
                &lt;span class='com'&gt;// если не получилось, то начинаем сначала&lt;/span&gt;
            }
            &lt;span class='com'&gt;// элемент ещё не готов для записи (очередь полна или типа того)&lt;/span&gt;
            &lt;span class='kw'&gt;else if&lt;/span&gt; (dif &amp;lt; 0)
                &lt;span class='kw'&gt;return false&lt;/span&gt;;
            &lt;span class='com'&gt;// нас кто-то опередил
            // перезагружаем текущий элемент и начинаем сначала&lt;/span&gt;
            &lt;span class='kw'&gt;else&lt;/span&gt; &lt;span class='com'&gt;/* if (dif &amp;gt; 0) */&lt;/span&gt;
                pos = enqueue_pos_.load(std::memory_order_relaxed);
        }

        &lt;span class='com'&gt;// в данной точке мы зарезервировали элемент для записи

        // пишем данные&lt;/span&gt;
        cell-&amp;gt;data_ = data;
        &lt;span class='com'&gt;// помечаем элемент как готовый для потребления&lt;/span&gt;
        cell-&amp;gt;sequence_.store(pos + 1, std::memory_order_release);

        &lt;span class='kw'&gt;return true&lt;/span&gt;;
    }

    &lt;span class='kw'&gt;bool&lt;/span&gt; dequeue(T&amp;amp; data)
    {
        cell_t* cell;
        &lt;span class='com'&gt;// загружаем текущую позицию для извлечения из очереди&lt;/span&gt;
        size_t pos = dequeue_pos_.load(std::memory_order_relaxed);
        &lt;span class='kw'&gt;for&lt;/span&gt; (;;)
        {
            &lt;span class='com'&gt;// находим текущий элемент&lt;/span&gt;
            cell = &amp;amp;buffer_[pos &amp;amp; buffer_mask_];
            &lt;span class='com'&gt;// загружаем статус (sequence) текущего элемента&lt;/span&gt;
            size_t seq = cell-&amp;gt;sequence_.load(std::memory_order_acquire);
            intptr_t dif = (intptr_t)seq - (intptr_t)(pos + 1);
            &lt;span class='com'&gt;// элемент готов для извлечения&lt;/span&gt;
            &lt;span class='kw'&gt;if&lt;/span&gt; (dif == 0)
            {
                &lt;span class='com'&gt;// пытаемся сдвинуть позицию для извлечения&lt;/span&gt;
                &lt;span class='kw'&gt;if&lt;/span&gt; (dequeue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed))
                    &lt;span class='kw'&gt;break&lt;/span&gt;;
                &lt;span class='com'&gt;// если не получилось, то начинаем сначала&lt;/span&gt;
            }
            &lt;span class='com'&gt;// элемент ещё не готов для потребления (очередь пуста или типа того)&lt;/span&gt;
            &lt;span class='kw'&gt;else if&lt;/span&gt; (dif &amp;lt; 0)
                &lt;span class='kw'&gt;return false&lt;/span&gt;;
            &lt;span class='com'&gt;// нас кто-то опередил
            // перезагружаем текущий элемент и начинаем сначала&lt;/span&gt;
            &lt;span class='kw'&gt;else&lt;/span&gt; &lt;span class='com'&gt;/* if (dif &amp;gt; 0) */&lt;/span&gt;
                pos = dequeue_pos_.load(std::memory_order_relaxed);
        }

        &lt;span class='com'&gt;// в данной точке мы зарезервировали элемент для чтения

        // читаем данные&lt;/span&gt;
        data = cell-&amp;gt;data_;
        &lt;span class='com'&gt;// помечаем элемент как готовый для следующей записи&lt;/span&gt;
        cell-&amp;gt;sequence_.store(pos + buffer_mask_ + 1, std::memory_order_release);

        &lt;span class='kw'&gt;return true&lt;/span&gt;;
    }

&lt;span class='kw'&gt;private&lt;/span&gt;:
    &lt;span class='kw'&gt;struct&lt;/span&gt; cell_t
    {
        std::atomic&amp;lt;size_t&amp;gt;     sequence_;
        T                       data_;
    };

    &lt;span class='kw'&gt;static&lt;/span&gt; size_t &lt;span class='kw'&gt;const&lt;/span&gt;         cacheline_size = 64;
    &lt;span class='kw'&gt;typedef char&lt;/span&gt;                cacheline_pad_t [cacheline_size];

    cacheline_pad_t             pad0_;
    cell_t* &lt;span class='kw'&gt;const&lt;/span&gt;               buffer_;
    size_t &lt;span class='kw'&gt;const&lt;/span&gt;                buffer_mask_;
    cacheline_pad_t             pad1_;
    std::atomic&amp;lt;size_t&amp;gt;         enqueue_pos_;
    cacheline_pad_t             pad2_;
    std::atomic&amp;lt;size_t&amp;gt;         dequeue_pos_;
    cacheline_pad_t             pad3_;

    mpmc_bounded_queue(mpmc_bounded_queue &lt;span class='kw'&gt;const&lt;/span&gt;&amp;amp;);
    &lt;span class='kw'&gt;void operator&lt;/span&gt; = (mpmc_bounded_queue &lt;span class='kw'&gt;const&lt;/span&gt;&amp;amp;);
};&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
И вот реализация подмножества C++0x std::atomic, необходимого для компиляции очереди (MSVC, x86-32):&lt;br /&gt;
&lt;table width='96%'&gt;&lt;tr&gt;&lt;td nowrap='nowrap' class='c'&gt;&lt;pre&gt;
&lt;span class='kw'&gt;#include&lt;/span&gt; &amp;lt;intrin.h&amp;gt;

&lt;span class='kw'&gt;enum&lt;/span&gt; memory_order
{
    memory_order_relaxed,
    memory_order_consume,
    memory_order_acquire,
    memory_order_release,
    memory_order_acq_rel,
    memory_order_seq_cst,
};

&lt;span class='kw'&gt;class&lt;/span&gt; atomic_uint
{
&lt;span class='kw'&gt;public&lt;/span&gt;:
    &lt;span class='kw'&gt;unsigned&lt;/span&gt; load(memory_order mo) &lt;span class='kw'&gt;const volatile&lt;/span&gt;
    {
        (&lt;span class='kw'&gt;void&lt;/span&gt;)mo;
        assert(mo == memory_order_relaxed
            || mo == memory_order_consume
            || mo == memory_order_acquire
            || mo == memory_order_seq_cst);
        &lt;span class='kw'&gt;unsigned&lt;/span&gt; v = val_;
        _ReadWriteBarrier();
        &lt;span class='kw'&gt;return&lt;/span&gt; v;
    }

    &lt;span class='kw'&gt;void&lt;/span&gt; store(&lt;span class='kw'&gt;unsigned&lt;/span&gt; v, memory_order mo) &lt;span class='kw'&gt;volatile&lt;/span&gt;
    {
        assert(mo == memory_order_relaxed
            || mo == memory_order_release
            || mo == memory_order_seq_cst);

        &lt;span class='kw'&gt;if&lt;/span&gt; (mo == memory_order_seq_cst)
        {
            _InterlockedExchange((&lt;span class='kw'&gt;long volatile&lt;/span&gt;*)&amp;amp;val_, (&lt;span class='kw'&gt;long&lt;/span&gt;)v);
        }
        &lt;span class='kw'&gt;else&lt;/span&gt;
        {
            val_ = v;
            _ReadWriteBarrier();
        }
    }

    &lt;span class='kw'&gt;bool&lt;/span&gt; compare_exchange_weak(&lt;span class='kw'&gt;unsigned&lt;/span&gt;&amp;amp; cmp, &lt;span class='kw'&gt;unsigned&lt;/span&gt; xchg, memory_order mo) &lt;span class='kw'&gt;volatile&lt;/span&gt;
    {
        &lt;span class='kw'&gt;unsigned&lt;/span&gt; prev = (&lt;span class='kw'&gt;unsigned&lt;/span&gt;)_InterlockedCompareExchange((&lt;span class='kw'&gt;long volatile&lt;/span&gt;*)&amp;amp;val_, (&lt;span class='kw'&gt;long&lt;/span&gt;)xchg, (&lt;span class='kw'&gt;long&lt;/span&gt;)cmp);
        &lt;span class='kw'&gt;if&lt;/span&gt; (prev == cmp)
            &lt;span class='kw'&gt;return true&lt;/span&gt;;
        cmp = prev;
        &lt;span class='kw'&gt;return false&lt;/span&gt;;
    }

&lt;span class='kw'&gt;private&lt;/span&gt;:
    &lt;span class='kw'&gt;unsigned volatile&lt;/span&gt;           val_;
};

&lt;span class='kw'&gt;template&lt;/span&gt;&amp;lt;&lt;span class='kw'&gt;typename&lt;/span&gt; T&amp;gt;
&lt;span class='kw'&gt;class&lt;/span&gt; atomic;

&lt;span class='kw'&gt;template&lt;/span&gt;&amp;lt;&amp;gt;
&lt;span class='kw'&gt;class&lt;/span&gt; atomic&amp;lt;&lt;span class='kw'&gt;unsigned&lt;/span&gt;&amp;gt; : &lt;span class='kw'&gt;public&lt;/span&gt; atomic_uint
{
};&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;img border='0' width='57' height='16' src='http://www.rsdn.ru/Forum/images/beer.gif' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/5Sm3AEEpW90" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Wed, 10 Mar 2010 17:09:44 GMT</pubDate>
		
			<author>remark &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>14</slash:comments>
		
	</item>

	<item>
		<title>SFINAE: hasMethos + isMethodProtected</title>
		<link>http://www.rsdn.ru/Forum/cpp/3730553.1.aspx</link>
		<guid isPermaLink="true">http://www.rsdn.ru/Forum/cpp/3730553.aspx</guid>
		<comments>http://www.rsdn.ru/Forum/cpp/3730553.aspx</comments>
		<wfw:comment>http://www.rsdn.ru/Forum/PostRssComment.aspx?mid=3730553</wfw:comment>
		<wfw:commentRss>http://www.rsdn.ru/Forum/RSS/3730553.aspx</wfw:commentRss>
		<trackback:ping>http://www.rsdn.ru/Forum/Trackback.aspx?mid=3730553</trackback:ping>
		<description>&lt;div style="@import url(http://www.rsdn.ru/Forum/Forum.css);"&gt;Привет, всем!&lt;br /&gt;
Вообщем, нужно проверить есть ли у класса метод и если есть, то в какой секции.&lt;br /&gt;
Проверить наличие метода это на аць-два, а вот с меткой доступа проблеммы.&lt;br /&gt;
не подскажете это вообще возможно?&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/rsdn/cpp/~4/93Zr0Xkrpx0" height="1" width="1"/&gt;</description>
		
		<category>cpp</category>
		<pubDate>Wed, 10 Mar 2010 13:55:19 GMT</pubDate>
		
			<author>SenkraD &lt;forum@rsdn.ru&gt;</author>
		
		
			<slash:comments>14</slash:comments>
		
	</item>
</channel>
</rss>
