<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[2^x-Flags &amp;quot;objektorientiert&amp;quot; simulieren]]></title><description><![CDATA[<p>Halli hallo!<br />
Und zwar stellte sich mir die Frage, ob es irgendeine nette und prägnante Art und Weise gibt, die 2^x-Flags, die man aus C so kennt vernünftig und &quot;Typsicher&quot; in C++ rüberzuretten und dabei die &quot;Beschränkung&quot; (Die man aber sowieso fast niemals erreicht bzw. natürlich umschiffen kann) auf die Anzahl von Flags aufzuweichen.</p>
<p>Ich habe mich mal daran versucht, aber wie ihr seht, kommt dabei ein Kauderwelsch raus. Ich frage mich, ob es eine total elegante Lösung dafür gibt.<br />
Am Ende dann mein &quot;Pseudo&quot;-Source.</p>
<p>Viele Grüße,<br />
Michael</p>
<pre><code class="language-cpp">#include &lt;bitset&gt;
#include &lt;iostream&gt;

struct null;

template&lt; int in1, int in2 &gt;
struct ct_max {
	static const int max_ = (in1 &gt; in2) ? in1 : in2;
};

template&lt; class base &gt;
struct counter {
    static const int count_ = base::count_ + 1;
};

template&lt; &gt;
struct counter&lt; null &gt; {
	static const int count_ = 0;
};

template&lt; class last_counter, class context &gt;
class flag_base
{
public:
	typedef context context_;
	typedef counter&lt; last_counter &gt; counter_;
	typedef flag_base&lt; counter_, context &gt; next_;
};

template&lt; unsigned int count, class context_ &gt;
struct flag_set
{
	void set( unsigned int which ) {
		flags_.set( which );
	}

	bool test( unsigned int which ) const {
		return which &lt; flags_.size() &amp;&amp; flags_.test( which );
	}

	template&lt; unsigned int count2 &gt;
	flag_set&amp; operator=( const flag_set&lt; count2, context_ &gt;&amp; f ) {
		flags_.reset();
		for( unsigned int i=0; i&lt;f.size_; ++i ) {
			flags_[i] = f.test(i);
		}
		return *this;
	}

    friend std::ostream&amp; operator&lt;&lt;( std::ostream&amp; o, const flag_set&lt; count, context_ &gt;&amp; fs )
    {
		o &lt;&lt; fs.flags_;
		return o;
    }

	static const int size_ = count;

private:
	std::bitset&lt; count &gt; flags_;
};

template&lt; class U, class V, class context &gt; 
flag_set&lt; ct_max&lt; flag_base&lt;U,context&gt;::counter_::count_, flag_base&lt;V,context&gt;::counter_::count_ &gt;::max_+1, context &gt;
operator|( const flag_base&lt;U, context&gt;&amp; f1, const flag_base&lt;V, context&gt;&amp; f2 )
{
	flag_set&lt; ct_max&lt; flag_base&lt;U,context&gt;::counter_::count_, flag_base&lt;V,context&gt;::counter_::count_ &gt;::max_+1, context &gt; temp;
	temp.set( flag_base&lt;U,context&gt;::counter_::count_ );
	temp.set( flag_base&lt;V,context&gt;::counter_::count_ );

	return temp;
}

template&lt; unsigned int U, class V, class context &gt;
flag_set&lt; ct_max&lt; flag_set&lt;U,context&gt;::size_, flag_base&lt;V,context&gt;::counter_::count_+1 &gt;::max_, context &gt;
operator|( const flag_set&lt; U,context &gt;&amp; f1, const flag_base&lt;V,context&gt;&amp; f2 ) {
    flag_set&lt; ct_max&lt; flag_set&lt;U,context&gt;::size_, flag_base&lt;V,context&gt;::counter_::count_+1 &gt;::max_, context &gt; temp;
    temp = f1;
    temp.set( flag_base&lt;V, context&gt;::counter_::count_ );
    return temp;
}

template&lt; unsigned int U, class V, class context &gt;
bool operator&amp;( const flag_set&lt;U,context&gt;&amp; f1, const flag_base&lt;V,context&gt;&amp; f2 ) {
	return f1.test( flag_base&lt;V,context&gt;::counter_::count_ );
}

struct myflags1 {};
class flag1_ : public flag_base&lt; null, myflags1 &gt; {}  flag1;
class flag2_ : public flag1_::next_ {}  flag2;
class flag3_ : public flag2_::next_ {}  flag3;
class flag4_ : public flag3_::next_ {}  flag4;

struct myflags2 {};
class flag_1 : public flag_base&lt; null, myflags2 &gt; {} flag1_1;

int main(int argc, char* argv[])
{
	std::cout &lt;&lt; ((flag1|flag2|flag3)&amp;flag4) &lt;&lt; std::endl;
	std::cout &lt;&lt; sizeof( flag4 );

	// std::cout &lt;&lt; (flag1|flag2)&amp;flag1_1 &lt;&lt; std::endl;
	return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/230456/2-x-flags-quot-objektorientiert-quot-simulieren</link><generator>RSS for Node</generator><lastBuildDate>Sun, 27 Sep 2026 07:59:18 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/230456.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 27 Dec 2008 00:49:35 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to 2^x-Flags &amp;quot;objektorientiert&amp;quot; simulieren on Sat, 27 Dec 2008 00:55:58 GMT]]></title><description><![CDATA[<p>Halli hallo!<br />
Und zwar stellte sich mir die Frage, ob es irgendeine nette und prägnante Art und Weise gibt, die 2^x-Flags, die man aus C so kennt vernünftig und &quot;Typsicher&quot; in C++ rüberzuretten und dabei die &quot;Beschränkung&quot; (Die man aber sowieso fast niemals erreicht bzw. natürlich umschiffen kann) auf die Anzahl von Flags aufzuweichen.</p>
<p>Ich habe mich mal daran versucht, aber wie ihr seht, kommt dabei ein Kauderwelsch raus. Ich frage mich, ob es eine total elegante Lösung dafür gibt.<br />
Am Ende dann mein &quot;Pseudo&quot;-Source.</p>
<p>Viele Grüße,<br />
Michael</p>
<pre><code class="language-cpp">#include &lt;bitset&gt;
#include &lt;iostream&gt;

struct null;

template&lt; int in1, int in2 &gt;
struct ct_max {
	static const int max_ = (in1 &gt; in2) ? in1 : in2;
};

template&lt; class base &gt;
struct counter {
    static const int count_ = base::count_ + 1;
};

template&lt; &gt;
struct counter&lt; null &gt; {
	static const int count_ = 0;
};

template&lt; class last_counter, class context &gt;
class flag_base
{
public:
	typedef context context_;
	typedef counter&lt; last_counter &gt; counter_;
	typedef flag_base&lt; counter_, context &gt; next_;
};

template&lt; unsigned int count, class context_ &gt;
struct flag_set
{
	void set( unsigned int which ) {
		flags_.set( which );
	}

	bool test( unsigned int which ) const {
		return which &lt; flags_.size() &amp;&amp; flags_.test( which );
	}

	template&lt; unsigned int count2 &gt;
	flag_set&amp; operator=( const flag_set&lt; count2, context_ &gt;&amp; f ) {
		flags_.reset();
		for( unsigned int i=0; i&lt;f.size_; ++i ) {
			flags_[i] = f.test(i);
		}
		return *this;
	}

    friend std::ostream&amp; operator&lt;&lt;( std::ostream&amp; o, const flag_set&lt; count, context_ &gt;&amp; fs )
    {
		o &lt;&lt; fs.flags_;
		return o;
    }

	static const int size_ = count;

private:
	std::bitset&lt; count &gt; flags_;
};

template&lt; class U, class V, class context &gt; 
flag_set&lt; ct_max&lt; flag_base&lt;U,context&gt;::counter_::count_, flag_base&lt;V,context&gt;::counter_::count_ &gt;::max_+1, context &gt;
operator|( const flag_base&lt;U, context&gt;&amp; f1, const flag_base&lt;V, context&gt;&amp; f2 )
{
	flag_set&lt; ct_max&lt; flag_base&lt;U,context&gt;::counter_::count_, flag_base&lt;V,context&gt;::counter_::count_ &gt;::max_+1, context &gt; temp;
	temp.set( flag_base&lt;U,context&gt;::counter_::count_ );
	temp.set( flag_base&lt;V,context&gt;::counter_::count_ );

	return temp;
}

template&lt; unsigned int U, class V, class context &gt;
flag_set&lt; ct_max&lt; flag_set&lt;U,context&gt;::size_, flag_base&lt;V,context&gt;::counter_::count_+1 &gt;::max_, context &gt;
operator|( const flag_set&lt; U,context &gt;&amp; f1, const flag_base&lt;V,context&gt;&amp; f2 ) {
    flag_set&lt; ct_max&lt; flag_set&lt;U,context&gt;::size_, flag_base&lt;V,context&gt;::counter_::count_+1 &gt;::max_, context &gt; temp;
    temp = f1;
    temp.set( flag_base&lt;V, context&gt;::counter_::count_ );
    return temp;
}

template&lt; unsigned int U, class V, class context &gt;
bool operator&amp;( const flag_set&lt;U,context&gt;&amp; f1, const flag_base&lt;V,context&gt;&amp; f2 ) {
	return f1.test( flag_base&lt;V,context&gt;::counter_::count_ );
}

struct myflags1 {};
class flag1_ : public flag_base&lt; null, myflags1 &gt; {}  flag1;
class flag2_ : public flag1_::next_ {}  flag2;
class flag3_ : public flag2_::next_ {}  flag3;
class flag4_ : public flag3_::next_ {}  flag4;

struct myflags2 {};
class flag_1 : public flag_base&lt; null, myflags2 &gt; {} flag1_1;

int main(int argc, char* argv[])
{
	std::cout &lt;&lt; ((flag1|flag2|flag3)&amp;flag4) &lt;&lt; std::endl;
	std::cout &lt;&lt; sizeof( flag4 );

	// std::cout &lt;&lt; (flag1|flag2)&amp;flag1_1 &lt;&lt; std::endl;
	return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1635981</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1635981</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Sat, 27 Dec 2008 00:55:58 GMT</pubDate></item><item><title><![CDATA[Reply to 2^x-Flags &amp;quot;objektorientiert&amp;quot; simulieren on Sat, 27 Dec 2008 16:41:35 GMT]]></title><description><![CDATA[<p>Wäre da nicht <code>std::bitset</code> eine Möglichkeit? Oder was versuchst du genau?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1636185</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1636185</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sat, 27 Dec 2008 16:41:35 GMT</pubDate></item></channel></rss>