[{"id":16573,"web_url":"https://patchwork.libcamera.org/comment/16573/","msgid":"<7e92148b-83ea-dd93-b437-0bba2b836d80@ideasonboard.com>","date":"2021-04-26T08:22:05","subject":"Re: [libcamera-devel] [PATCH 2/2] test: Add tests for the Flags\n\tclass","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"On 25/07/2020 00:08, Laurent Pinchart wrote:\n> Add tests that exercise the whole API of the Flags class.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  test/flags.cpp   | 204 +++++++++++++++++++++++++++++++++++++++++++++++\n>  test/meson.build |   1 +\n>  2 files changed, 205 insertions(+)\n>  create mode 100644 test/flags.cpp\n> \n> diff --git a/test/flags.cpp b/test/flags.cpp\n> new file mode 100644\n> index 000000000000..82eca556f35e\n> --- /dev/null\n> +++ b/test/flags.cpp\n> @@ -0,0 +1,204 @@\n> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> +/*\n> + * Copyright (C) 2020, Google Inc.\n> + *\n> + * flags.cpp - Flags tests\n> + */\n> +\n> +#include <iostream>\n> +\n> +#include <libcamera/flags.h>\n> +\n> +#include \"test.h\"\n> +\n> +using namespace libcamera;\n> +using namespace std;\n> +\n> +class FlagsTest : public Test\n> +{\n> +protected:\n> +\tenum class Option {\n> +\t\tFirst = (1 << 0),\n> +\t\tSecond = (1 << 1),\n> +\t\tThird = (1 << 2),\n> +\t};\n> +\n> +\tusing Options = Flags<Option>;\n> +\n> +\tenum class Mode {\n> +\t\tAlpha = (1 << 0),\n> +\t\tBeta = (1 << 2),\n> +\t\tGamma = (1 << 2),\n\nI have to wonder if this is an intentional 'fault' ?\n\nOr is there be a better way to ensure that the bit field enums are not\nincorrectly duplicated?\nAn enum automatically assigns numbers, so it's a shame to take the\nautomatic assignment, and replace it with a manual error prone detail.\n\nUnfortunately I don't expect there's a way to make an enum automatically\n<<= 1 instead of += 1\n\n\n\n> +\t};\n> +\n> +\tusing Modes = Flags<Mode>;\n> +\n> +\tint run() override;\n> +};\n> +\n> +namespace libcamera {\n> +\n> +LIBCAMERA_FLAGS_ENABLE_OPERATORS(FlagsTest::Option)\n> +\n> +} /* namespace libcamera */\n> +\n> +int FlagsTest::run()\n> +{\n> +\t/* Commented-out constructs are expected not compile. */\n> +\n> +\t/* Flags<int> f; */\n> +\n> +\t/*\n> +\t * Unary operators with enum argument.\n> +\t */\n> +\n> +\tOptions options;\n> +\n> +\tif (options) {\n> +\t\tcerr << \"Default-constructed Flags<> is not zero\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\toptions |= Option::First;\n> +\n> +\tif (!options || options != Option::First) {\n> +\t\tcerr << \"Unary bitwise OR with enum failed\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\t/* options &= Mode::Alpha; */\n> +\t/* options |= Mode::Beta;  */\n> +\t/* options ^= Mode::Gamma; */\n> +\n> +\toptions &= ~Option::First;\n> +\n> +\tif (options) {\n> +\t\tcerr << \"Unary bitwise AND with enum failed\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\toptions ^= Option::Second;\n> +\n> +\tif (options != Option::Second) {\n> +\t\tcerr << \"Unary bitwise XOR with enum failed\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\toptions = Options();\n> +\n> +\t/*\n> +\t * Unary operators with Flags argument.\n> +\t */\n> +\n> +\toptions |= Options(Option::First);\n> +\n> +\tif (options != Option::First) {\n> +\t\tcerr << \"Unary bitwise OR with Flags<> failed\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\t/* options &= Options(Mode::Alpha); */\n> +\t/* options |= Options(Mode::Beta);  */\n> +\t/* options ^= Options(Mode::Gamma); */\n> +\n> +\toptions &= ~Options(Option::First);\n> +\n> +\tif (options) {\n> +\t\tcerr << \"Unary bitwise AND with Flags<> failed\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\toptions ^= Options(Option::Second);\n> +\n> +\tif (options != Option::Second) {\n> +\t\tcerr << \"Unary bitwise XOR with Flags<> failed\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\toptions = Options();\n> +\n> +\t/*\n> +\t * Binary operators with enum argument.\n> +\t */\n> +\n> +\toptions = options | Option::First;\n> +\n> +\tif (!(options & Option::First)) {\n> +\t\tcerr << \"Binary bitwise OR with enum failed\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\t/* options = options & Mode::Alpha; */\n> +\t/* options = options | Mode::Beta;  */\n> +\t/* options = options ^ Mode::Gamma; */\n> +\n> +\toptions = options & ~Option::First;\n> +\n> +\tif (options != (Option::First & Option::Second)) {\n> +\t\tcerr << \"Binary bitwise AND with enum failed\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\toptions = options ^ (Option::First ^ Option::Second);\n> +\n> +\tif (options != (Option::First | Option::Second)) {\n> +\t\tcerr << \"Binary bitwise XOR with enum failed\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\toptions = Options();\n> +\n> +\t/*\n> +\t * Binary operators with Flags argument.\n> +\t */\n> +\n> +\toptions |= Options(Option::First);\n> +\n> +\tif (!(options & Option::First)) {\n> +\t\tcerr << \"Binary bitwise OR with Flags<> failed\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\t/* options = options & Options(Mode::Alpha); */\n> +\t/* options = options | Options(Mode::Beta);  */\n> +\t/* options = options ^ Options(Mode::Gamma); */\n> +\n> +\toptions = options & ~Options(Option::First);\n> +\n> +\tif (options) {\n> +\t\tcerr << \"Binary bitwise AND with Flags<> failed\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\toptions = options ^ Options(Option::Second);\n> +\n> +\tif (options != Option::Second) {\n> +\t\tcerr << \"Binary bitwise XOR with Flags<> failed\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\toptions = Options();\n> +\n> +\t/*\n> +\t * Conversion operators.\n> +\t */\n> +\toptions |= Option::First | Option::Second | Option::Third;\n> +\tif (static_cast<Options::Type>(options) != 7) {\n> +\t\tcerr << \"Cast to underlying type failed\" << endl;\n> +\t\treturn TestFail;\n> +\t}\n> +\n> +\t/*\n> +\t * Conversion of the result of ninary operators on the underlying enum.\n> +\t */\n> +\n> +\t/* unsigned int val1 = Option::First; */\n> +\t/* unsigned int val2 = ~Option::First; */\n> +\t/* unsigned int val3 = Option::First | Option::Second; */\n> +\t/* Option val4 = ~Option::First; */\n> +\t/* Option val5 = Option::First | Option::Second; */\n> +\n> +\treturn TestPass;\n> +}\n> +\n> +TEST_REGISTER(FlagsTest)\n> diff --git a/test/meson.build b/test/meson.build\n> index f41d6e740e6a..81b20521e8cb 100644\n> --- a/test/meson.build\n> +++ b/test/meson.build\n> @@ -31,6 +31,7 @@ internal_tests = [\n>      ['event-thread',                    'event-thread.cpp'],\n>      ['file',                            'file.cpp'],\n>      ['file-descriptor',                 'file-descriptor.cpp'],\n> +    ['flags',                           'flags.cpp'],\n>      ['hotplug-cameras',                 'hotplug-cameras.cpp'],\n>      ['message',                         'message.cpp'],\n>      ['object',                          'object.cpp'],\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B02C6BDC99\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 26 Apr 2021 08:22:09 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B326568882;\n\tMon, 26 Apr 2021 10:22:08 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C7AA5602D1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 26 Apr 2021 10:22:07 +0200 (CEST)","from [192.168.0.20]\n\t(cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4926CD8B;\n\tMon, 26 Apr 2021 10:22:07 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"GTMIl78e\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1619425327;\n\tbh=vMCy+VjDDvur3YA51aZk3qMBbYqdXTE2v5PmCZg2j2k=;\n\th=Reply-To:To:References:From:Subject:Date:In-Reply-To:From;\n\tb=GTMIl78eTGrvbl8E7OKVlwnykGT9P4otYgylEfmdSgZ3OOl1DmYWSx9NWTLJujafG\n\t2tUu+UizEi4xhrYzMkTqLn4lLp8s1vngeY1qi0iTvFl6vDUzA6Tk7u7WtbjQkVJxRy\n\tBWXVKCZkJ3e/Pgh4JLAJlvdFt7gtCVIO5BzNt03w=","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20200724230841.27838-1-laurent.pinchart@ideasonboard.com>\n\t<20200724230841.27838-3-laurent.pinchart@ideasonboard.com>","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Organization":"Ideas on Board","Message-ID":"<7e92148b-83ea-dd93-b437-0bba2b836d80@ideasonboard.com>","Date":"Mon, 26 Apr 2021 09:22:05 +0100","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.7.1","MIME-Version":"1.0","In-Reply-To":"<20200724230841.27838-3-laurent.pinchart@ideasonboard.com>","Content-Language":"en-GB","Subject":"Re: [libcamera-devel] [PATCH 2/2] test: Add tests for the Flags\n\tclass","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Reply-To":"kieran.bingham@ideasonboard.com","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":16574,"web_url":"https://patchwork.libcamera.org/comment/16574/","msgid":"<YIZ7KinEa39N0/ri@pendragon.ideasonboard.com>","date":"2021-04-26T08:34:50","subject":"Re: [libcamera-devel] [PATCH 2/2] test: Add tests for the Flags\n\tclass","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Kieran,\n\nOn Mon, Apr 26, 2021 at 09:22:05AM +0100, Kieran Bingham wrote:\n> On 25/07/2020 00:08, Laurent Pinchart wrote:\n> > Add tests that exercise the whole API of the Flags class.\n> > \n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >  test/flags.cpp   | 204 +++++++++++++++++++++++++++++++++++++++++++++++\n> >  test/meson.build |   1 +\n> >  2 files changed, 205 insertions(+)\n> >  create mode 100644 test/flags.cpp\n> > \n> > diff --git a/test/flags.cpp b/test/flags.cpp\n> > new file mode 100644\n> > index 000000000000..82eca556f35e\n> > --- /dev/null\n> > +++ b/test/flags.cpp\n> > @@ -0,0 +1,204 @@\n> > +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> > +/*\n> > + * Copyright (C) 2020, Google Inc.\n> > + *\n> > + * flags.cpp - Flags tests\n> > + */\n> > +\n> > +#include <iostream>\n> > +\n> > +#include <libcamera/flags.h>\n> > +\n> > +#include \"test.h\"\n> > +\n> > +using namespace libcamera;\n> > +using namespace std;\n> > +\n> > +class FlagsTest : public Test\n> > +{\n> > +protected:\n> > +\tenum class Option {\n> > +\t\tFirst = (1 << 0),\n> > +\t\tSecond = (1 << 1),\n> > +\t\tThird = (1 << 2),\n> > +\t};\n> > +\n> > +\tusing Options = Flags<Option>;\n> > +\n> > +\tenum class Mode {\n> > +\t\tAlpha = (1 << 0),\n> > +\t\tBeta = (1 << 2),\n> > +\t\tGamma = (1 << 2),\n> \n> I have to wonder if this is an intentional 'fault' ?\n\nOops. Absolutely non-intentional.\n\n> Or is there be a better way to ensure that the bit field enums are not\n> incorrectly duplicated?\n> An enum automatically assigns numbers, so it's a shame to take the\n> automatic assignment, and replace it with a manual error prone detail.\n> \n> Unfortunately I don't expect there's a way to make an enum automatically\n> <<= 1 instead of += 1\n\nIt may be possible to tweak the Flags class to do this. Anyone wants to\nhave fun with templates ? :-)\n\n> > +\t};\n> > +\n> > +\tusing Modes = Flags<Mode>;\n> > +\n> > +\tint run() override;\n> > +};\n> > +\n> > +namespace libcamera {\n> > +\n> > +LIBCAMERA_FLAGS_ENABLE_OPERATORS(FlagsTest::Option)\n> > +\n> > +} /* namespace libcamera */\n> > +\n> > +int FlagsTest::run()\n> > +{\n> > +\t/* Commented-out constructs are expected not compile. */\n> > +\n> > +\t/* Flags<int> f; */\n> > +\n> > +\t/*\n> > +\t * Unary operators with enum argument.\n> > +\t */\n> > +\n> > +\tOptions options;\n> > +\n> > +\tif (options) {\n> > +\t\tcerr << \"Default-constructed Flags<> is not zero\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\toptions |= Option::First;\n> > +\n> > +\tif (!options || options != Option::First) {\n> > +\t\tcerr << \"Unary bitwise OR with enum failed\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\t/* options &= Mode::Alpha; */\n> > +\t/* options |= Mode::Beta;  */\n> > +\t/* options ^= Mode::Gamma; */\n> > +\n> > +\toptions &= ~Option::First;\n> > +\n> > +\tif (options) {\n> > +\t\tcerr << \"Unary bitwise AND with enum failed\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\toptions ^= Option::Second;\n> > +\n> > +\tif (options != Option::Second) {\n> > +\t\tcerr << \"Unary bitwise XOR with enum failed\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\toptions = Options();\n> > +\n> > +\t/*\n> > +\t * Unary operators with Flags argument.\n> > +\t */\n> > +\n> > +\toptions |= Options(Option::First);\n> > +\n> > +\tif (options != Option::First) {\n> > +\t\tcerr << \"Unary bitwise OR with Flags<> failed\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\t/* options &= Options(Mode::Alpha); */\n> > +\t/* options |= Options(Mode::Beta);  */\n> > +\t/* options ^= Options(Mode::Gamma); */\n> > +\n> > +\toptions &= ~Options(Option::First);\n> > +\n> > +\tif (options) {\n> > +\t\tcerr << \"Unary bitwise AND with Flags<> failed\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\toptions ^= Options(Option::Second);\n> > +\n> > +\tif (options != Option::Second) {\n> > +\t\tcerr << \"Unary bitwise XOR with Flags<> failed\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\toptions = Options();\n> > +\n> > +\t/*\n> > +\t * Binary operators with enum argument.\n> > +\t */\n> > +\n> > +\toptions = options | Option::First;\n> > +\n> > +\tif (!(options & Option::First)) {\n> > +\t\tcerr << \"Binary bitwise OR with enum failed\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\t/* options = options & Mode::Alpha; */\n> > +\t/* options = options | Mode::Beta;  */\n> > +\t/* options = options ^ Mode::Gamma; */\n> > +\n> > +\toptions = options & ~Option::First;\n> > +\n> > +\tif (options != (Option::First & Option::Second)) {\n> > +\t\tcerr << \"Binary bitwise AND with enum failed\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\toptions = options ^ (Option::First ^ Option::Second);\n> > +\n> > +\tif (options != (Option::First | Option::Second)) {\n> > +\t\tcerr << \"Binary bitwise XOR with enum failed\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\toptions = Options();\n> > +\n> > +\t/*\n> > +\t * Binary operators with Flags argument.\n> > +\t */\n> > +\n> > +\toptions |= Options(Option::First);\n> > +\n> > +\tif (!(options & Option::First)) {\n> > +\t\tcerr << \"Binary bitwise OR with Flags<> failed\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\t/* options = options & Options(Mode::Alpha); */\n> > +\t/* options = options | Options(Mode::Beta);  */\n> > +\t/* options = options ^ Options(Mode::Gamma); */\n> > +\n> > +\toptions = options & ~Options(Option::First);\n> > +\n> > +\tif (options) {\n> > +\t\tcerr << \"Binary bitwise AND with Flags<> failed\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\toptions = options ^ Options(Option::Second);\n> > +\n> > +\tif (options != Option::Second) {\n> > +\t\tcerr << \"Binary bitwise XOR with Flags<> failed\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\toptions = Options();\n> > +\n> > +\t/*\n> > +\t * Conversion operators.\n> > +\t */\n> > +\toptions |= Option::First | Option::Second | Option::Third;\n> > +\tif (static_cast<Options::Type>(options) != 7) {\n> > +\t\tcerr << \"Cast to underlying type failed\" << endl;\n> > +\t\treturn TestFail;\n> > +\t}\n> > +\n> > +\t/*\n> > +\t * Conversion of the result of ninary operators on the underlying enum.\n> > +\t */\n> > +\n> > +\t/* unsigned int val1 = Option::First; */\n> > +\t/* unsigned int val2 = ~Option::First; */\n> > +\t/* unsigned int val3 = Option::First | Option::Second; */\n> > +\t/* Option val4 = ~Option::First; */\n> > +\t/* Option val5 = Option::First | Option::Second; */\n> > +\n> > +\treturn TestPass;\n> > +}\n> > +\n> > +TEST_REGISTER(FlagsTest)\n> > diff --git a/test/meson.build b/test/meson.build\n> > index f41d6e740e6a..81b20521e8cb 100644\n> > --- a/test/meson.build\n> > +++ b/test/meson.build\n> > @@ -31,6 +31,7 @@ internal_tests = [\n> >      ['event-thread',                    'event-thread.cpp'],\n> >      ['file',                            'file.cpp'],\n> >      ['file-descriptor',                 'file-descriptor.cpp'],\n> > +    ['flags',                           'flags.cpp'],\n> >      ['hotplug-cameras',                 'hotplug-cameras.cpp'],\n> >      ['message',                         'message.cpp'],\n> >      ['object',                          'object.cpp'],","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 6C1DABDC95\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 26 Apr 2021 08:34:58 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id BDEC4688AE;\n\tMon, 26 Apr 2021 10:34:57 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id DCE46602D1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 26 Apr 2021 10:34:56 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 582BBD8B;\n\tMon, 26 Apr 2021 10:34:56 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"roQUPhub\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1619426096;\n\tbh=sAhbQ5M5hY5iyx/aVGLZMkJXPKOKLWLw0vCyKDelflE=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=roQUPhub4bcKNItWGO9SPyNg5do/xAewkQNqiCaWeTnA4bBrOcBy7I83YsaV44NQo\n\tGhbKzccSBtZO9AUnvwJWzg/tTOpisiu2Qm7bicZQNLcFw0NhELlcMhrqR6seTcB0Zu\n\tzoK3gj2RVb/ONGoDSz5H7d/gCVVQBjdmy8SRuyrY=","Date":"Mon, 26 Apr 2021 11:34:50 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Message-ID":"<YIZ7KinEa39N0/ri@pendragon.ideasonboard.com>","References":"<20200724230841.27838-1-laurent.pinchart@ideasonboard.com>\n\t<20200724230841.27838-3-laurent.pinchart@ideasonboard.com>\n\t<7e92148b-83ea-dd93-b437-0bba2b836d80@ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<7e92148b-83ea-dd93-b437-0bba2b836d80@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 2/2] test: Add tests for the Flags\n\tclass","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":16589,"web_url":"https://patchwork.libcamera.org/comment/16589/","msgid":"<be16f04a-e82e-a521-aaec-4c3b88810f77@ideasonboard.com>","date":"2021-04-26T11:51:40","subject":"Re: [libcamera-devel] [PATCH 2/2] test: Add tests for the Flags\n\tclass","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"On 26/04/2021 09:34, Laurent Pinchart wrote:\n> Hi Kieran,\n> \n> On Mon, Apr 26, 2021 at 09:22:05AM +0100, Kieran Bingham wrote:\n>> On 25/07/2020 00:08, Laurent Pinchart wrote:\n>>> Add tests that exercise the whole API of the Flags class.\n>>>\n>>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>>> ---\n>>>  test/flags.cpp   | 204 +++++++++++++++++++++++++++++++++++++++++++++++\n>>>  test/meson.build |   1 +\n>>>  2 files changed, 205 insertions(+)\n>>>  create mode 100644 test/flags.cpp\n>>>\n>>> diff --git a/test/flags.cpp b/test/flags.cpp\n>>> new file mode 100644\n>>> index 000000000000..82eca556f35e\n>>> --- /dev/null\n>>> +++ b/test/flags.cpp\n>>> @@ -0,0 +1,204 @@\n>>> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n>>> +/*\n>>> + * Copyright (C) 2020, Google Inc.\n>>> + *\n>>> + * flags.cpp - Flags tests\n>>> + */\n>>> +\n>>> +#include <iostream>\n>>> +\n>>> +#include <libcamera/flags.h>\n>>> +\n>>> +#include \"test.h\"\n>>> +\n>>> +using namespace libcamera;\n>>> +using namespace std;\n>>> +\n>>> +class FlagsTest : public Test\n>>> +{\n>>> +protected:\n>>> +\tenum class Option {\n>>> +\t\tFirst = (1 << 0),\n>>> +\t\tSecond = (1 << 1),\n>>> +\t\tThird = (1 << 2),\n>>> +\t};\n>>> +\n>>> +\tusing Options = Flags<Option>;\n>>> +\n>>> +\tenum class Mode {\n>>> +\t\tAlpha = (1 << 0),\n>>> +\t\tBeta = (1 << 2),\n>>> +\t\tGamma = (1 << 2),\n>>\n>> I have to wonder if this is an intentional 'fault' ?\n> \n> Oops. Absolutely non-intentional.\n> \n>> Or is there be a better way to ensure that the bit field enums are not\n>> incorrectly duplicated?\n>> An enum automatically assigns numbers, so it's a shame to take the\n>> automatic assignment, and replace it with a manual error prone detail.\n>>\n>> Unfortunately I don't expect there's a way to make an enum automatically\n>> <<= 1 instead of += 1\n> \n> It may be possible to tweak the Flags class to do this. Anyone wants to\n> have fun with templates ? :-)\n\n\nNot entirely fond of this but I asked on a CPP discord channel and\nsomeone suggested it can be done with X-Macro, which seems to be some\nexisting macro pattern.\n\n   https://godbolt.org/z/EnEWoeGYv\n\nI suspect perhaps that could be wrapped into a template too, which might\npotentially be more friendly than the continuous line X() X() X() macro..\n\n\n\n>>> +\t};\n>>> +\n>>> +\tusing Modes = Flags<Mode>;\n>>> +\n>>> +\tint run() override;\n>>> +};\n>>> +\n>>> +namespace libcamera {\n>>> +\n>>> +LIBCAMERA_FLAGS_ENABLE_OPERATORS(FlagsTest::Option)\n>>> +\n>>> +} /* namespace libcamera */\n>>> +\n>>> +int FlagsTest::run()\n>>> +{\n>>> +\t/* Commented-out constructs are expected not compile. */\n>>> +\n>>> +\t/* Flags<int> f; */\n>>> +\n>>> +\t/*\n>>> +\t * Unary operators with enum argument.\n>>> +\t */\n>>> +\n>>> +\tOptions options;\n>>> +\n>>> +\tif (options) {\n>>> +\t\tcerr << \"Default-constructed Flags<> is not zero\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\toptions |= Option::First;\n>>> +\n>>> +\tif (!options || options != Option::First) {\n>>> +\t\tcerr << \"Unary bitwise OR with enum failed\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\t/* options &= Mode::Alpha; */\n>>> +\t/* options |= Mode::Beta;  */\n>>> +\t/* options ^= Mode::Gamma; */\n>>> +\n>>> +\toptions &= ~Option::First;\n>>> +\n>>> +\tif (options) {\n>>> +\t\tcerr << \"Unary bitwise AND with enum failed\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\toptions ^= Option::Second;\n>>> +\n>>> +\tif (options != Option::Second) {\n>>> +\t\tcerr << \"Unary bitwise XOR with enum failed\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\toptions = Options();\n>>> +\n>>> +\t/*\n>>> +\t * Unary operators with Flags argument.\n>>> +\t */\n>>> +\n>>> +\toptions |= Options(Option::First);\n>>> +\n>>> +\tif (options != Option::First) {\n>>> +\t\tcerr << \"Unary bitwise OR with Flags<> failed\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\t/* options &= Options(Mode::Alpha); */\n>>> +\t/* options |= Options(Mode::Beta);  */\n>>> +\t/* options ^= Options(Mode::Gamma); */\n>>> +\n>>> +\toptions &= ~Options(Option::First);\n>>> +\n>>> +\tif (options) {\n>>> +\t\tcerr << \"Unary bitwise AND with Flags<> failed\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\toptions ^= Options(Option::Second);\n>>> +\n>>> +\tif (options != Option::Second) {\n>>> +\t\tcerr << \"Unary bitwise XOR with Flags<> failed\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\toptions = Options();\n>>> +\n>>> +\t/*\n>>> +\t * Binary operators with enum argument.\n>>> +\t */\n>>> +\n>>> +\toptions = options | Option::First;\n>>> +\n>>> +\tif (!(options & Option::First)) {\n>>> +\t\tcerr << \"Binary bitwise OR with enum failed\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\t/* options = options & Mode::Alpha; */\n>>> +\t/* options = options | Mode::Beta;  */\n>>> +\t/* options = options ^ Mode::Gamma; */\n>>> +\n>>> +\toptions = options & ~Option::First;\n>>> +\n>>> +\tif (options != (Option::First & Option::Second)) {\n>>> +\t\tcerr << \"Binary bitwise AND with enum failed\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\toptions = options ^ (Option::First ^ Option::Second);\n>>> +\n>>> +\tif (options != (Option::First | Option::Second)) {\n>>> +\t\tcerr << \"Binary bitwise XOR with enum failed\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\toptions = Options();\n>>> +\n>>> +\t/*\n>>> +\t * Binary operators with Flags argument.\n>>> +\t */\n>>> +\n>>> +\toptions |= Options(Option::First);\n>>> +\n>>> +\tif (!(options & Option::First)) {\n>>> +\t\tcerr << \"Binary bitwise OR with Flags<> failed\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\t/* options = options & Options(Mode::Alpha); */\n>>> +\t/* options = options | Options(Mode::Beta);  */\n>>> +\t/* options = options ^ Options(Mode::Gamma); */\n>>> +\n>>> +\toptions = options & ~Options(Option::First);\n>>> +\n>>> +\tif (options) {\n>>> +\t\tcerr << \"Binary bitwise AND with Flags<> failed\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\toptions = options ^ Options(Option::Second);\n>>> +\n>>> +\tif (options != Option::Second) {\n>>> +\t\tcerr << \"Binary bitwise XOR with Flags<> failed\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\toptions = Options();\n>>> +\n>>> +\t/*\n>>> +\t * Conversion operators.\n>>> +\t */\n>>> +\toptions |= Option::First | Option::Second | Option::Third;\n>>> +\tif (static_cast<Options::Type>(options) != 7) {\n>>> +\t\tcerr << \"Cast to underlying type failed\" << endl;\n>>> +\t\treturn TestFail;\n>>> +\t}\n>>> +\n>>> +\t/*\n>>> +\t * Conversion of the result of ninary operators on the underlying enum.\n>>> +\t */\n>>> +\n>>> +\t/* unsigned int val1 = Option::First; */\n>>> +\t/* unsigned int val2 = ~Option::First; */\n>>> +\t/* unsigned int val3 = Option::First | Option::Second; */\n>>> +\t/* Option val4 = ~Option::First; */\n>>> +\t/* Option val5 = Option::First | Option::Second; */\n>>> +\n>>> +\treturn TestPass;\n>>> +}\n>>> +\n>>> +TEST_REGISTER(FlagsTest)\n>>> diff --git a/test/meson.build b/test/meson.build\n>>> index f41d6e740e6a..81b20521e8cb 100644\n>>> --- a/test/meson.build\n>>> +++ b/test/meson.build\n>>> @@ -31,6 +31,7 @@ internal_tests = [\n>>>      ['event-thread',                    'event-thread.cpp'],\n>>>      ['file',                            'file.cpp'],\n>>>      ['file-descriptor',                 'file-descriptor.cpp'],\n>>> +    ['flags',                           'flags.cpp'],\n>>>      ['hotplug-cameras',                 'hotplug-cameras.cpp'],\n>>>      ['message',                         'message.cpp'],\n>>>      ['object',                          'object.cpp'],\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 16581BDC9C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 26 Apr 2021 11:51:46 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4C98968882;\n\tMon, 26 Apr 2021 13:51:45 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D730A605BE\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 26 Apr 2021 13:51:43 +0200 (CEST)","from [192.168.0.20]\n\t(cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 3AB994FB;\n\tMon, 26 Apr 2021 13:51:43 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"XngTDZYS\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1619437903;\n\tbh=JT/3toIbo2PI62v3WrQeq3b7w5BXeaG193WvfzbxRfs=;\n\th=Reply-To:Subject:To:Cc:References:From:Date:In-Reply-To:From;\n\tb=XngTDZYSZ6Jg4l7s2ajrCTT/c/dSaFJz/i1K3bRHgt5+CQkVJuHVVSiuvmPYmuPf0\n\t5/9Cay50e350Blc/B1/yMgsN7hx5dl6LuhvOiEFL0otD/5Bph06CogoqiubKftuGjK\n\ty4py0SISvxJE3EUXgG2yVlRUz6lfLcKBMspdDYTg=","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20200724230841.27838-1-laurent.pinchart@ideasonboard.com>\n\t<20200724230841.27838-3-laurent.pinchart@ideasonboard.com>\n\t<7e92148b-83ea-dd93-b437-0bba2b836d80@ideasonboard.com>\n\t<YIZ7KinEa39N0/ri@pendragon.ideasonboard.com>","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Organization":"Ideas on Board","Message-ID":"<be16f04a-e82e-a521-aaec-4c3b88810f77@ideasonboard.com>","Date":"Mon, 26 Apr 2021 12:51:40 +0100","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.7.1","MIME-Version":"1.0","In-Reply-To":"<YIZ7KinEa39N0/ri@pendragon.ideasonboard.com>","Content-Language":"en-GB","Subject":"Re: [libcamera-devel] [PATCH 2/2] test: Add tests for the Flags\n\tclass","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Reply-To":"kieran.bingham@ideasonboard.com","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]