[{"id":17190,"web_url":"https://patchwork.libcamera.org/comment/17190/","msgid":"<20210524115852.tea4nzfcd7v5tiel@uno.localdomain>","date":"2021-05-24T11:58:52","subject":"Re: [libcamera-devel] [PATCH v4 1/4] libcamera: utils: Add helper\n\tclass for std::chrono::duration","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Naush,\n\nOn Mon, May 24, 2021 at 09:48:19AM +0100, Naushir Patuck wrote:\n> A new utils::Duration class is defined to represent a\n> std::chrono::duration type with double precision nanosecond timebase.\n> Using a double minimises the loss of precision when converting timebases.\n> This helper class may be used by IPAs to represent variables such as frame\n> durations and exposure times.\n>\n> An operator << overload is define to help with displaying\n> utils::Duration value in stream objects. Currently, this will display\n> the duration value in microseconds.\n>\n> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>\n> Reviewed-by: David Plowman <david.plowman@raspberrypi.com>\n> ---\n>  include/libcamera/internal/utils.h | 42 ++++++++++++++++++++++++++++++\n>  src/libcamera/utils.cpp            | 41 +++++++++++++++++++++++++++++\n>  2 files changed, 83 insertions(+)\n>\n> diff --git a/include/libcamera/internal/utils.h b/include/libcamera/internal/utils.h\n> index 83dada7cc16c..f536f2267d70 100644\n> --- a/include/libcamera/internal/utils.h\n> +++ b/include/libcamera/internal/utils.h\n> @@ -316,8 +316,50 @@ auto enumerate(T (&iterable)[N]) -> details::enumerate_adapter<T *>\n>  }\n>  #endif\n>\n> +class Duration : public std::chrono::duration<double, std::nano>\n> +{\n> +\tusing BaseDuration = std::chrono::duration<double, std::nano>;\n> +\n> +public:\n> +\tDuration() = default;\n> +\n> +\ttemplate<typename Rep, typename Period>\n> +\tconstexpr Duration(const std::chrono::duration<Rep, Period> &d)\n> +\t\t: BaseDuration(d)\n> +\t{\n> +\t}\n> +\n> +\ttemplate<typename Period>\n> +\tdouble get() const\n> +\t{\n> +\t\tauto const c = std::chrono::duration_cast<std::chrono::duration<double, Period>>(*this);\n> +\t\treturn c.count();\n> +\t}\n> +\n> +\texplicit constexpr operator bool() const\n> +\t{\n> +\t\treturn *this != BaseDuration::zero();\n> +\t}\n> +};\n> +\n>  } /* namespace utils */\n>\n> +#ifndef __DOXYGEN__\n> +template<class CharT, class Traits>\n> +static inline std::basic_ostream<CharT, Traits> &operator<<(std::basic_ostream<CharT, Traits> &os,\n> +\t\t\t\t\t\t\t    const utils::Duration &d)\n> +{\n> +\tstd::basic_ostringstream<CharT, Traits> s;\n> +\n> +\ts.flags(os.flags());\n> +\ts.imbue(os.getloc());\n> +\ts.setf(std::ios_base::fixed, std::ios_base::floatfield);\n> +\ts.precision(2);\n> +\ts << d.get<std::micro>() << \"us\";\n> +\treturn os << s.str();\n> +}\n> +#endif\n> +\n>  } /* namespace libcamera */\n>\n>  #endif /* __LIBCAMERA_INTERNAL_UTILS_H__ */\n> diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp\n> index 826144d3c837..480284c6c2c9 100644\n> --- a/src/libcamera/utils.cpp\n> +++ b/src/libcamera/utils.cpp\n> @@ -506,6 +506,47 @@ std::string libcameraSourcePath()\n>   * loop, iterates over an indexed view of the \\a iterable\n>   */\n>\n> +/**\n> + * \\class Duration\n> + * \\brief Helper class for std::chrono::duration types\n\nHelper class derived from std::chrono::duration that represents a time\nduration in nanoseconds with double precision\n\n> + */\n> +\n> +/**\n> + * \\typedef Duration::BaseDuration\n> + * \\brief Base struct for the \\a Duration helper class\n> + */\n\nIsn't this private ? does it need documentation ? It's just a\nsyntactic sugar used in the class definition, isn't it ?\n\n\n> +\n> +/**\n> + * \\fn Duration::Duration(const std::chrono::duration<Rep, Period> &d)\n> + * \\brief Copy constructor from a \\a std::chrono::duration type\n> + * \\param[in] d The std::chrono::duration object to convert from\n> + *\n> + * Constructs a \\a Duration object from a \\a std::chrono::duration object,\n> + * internally converting the representation to \\a Duration::BaseDuration type\n> + */\n> +\n> +/**\n> + * \\fn Duration::get<Period>()\n> + * \\brief Retrieve the tick count, converted to the timebase provided by the\n> + * template argument Period of type \\a std::ratio\n> + *\n> + * A typical usage example is given below:\n> + *\n> + * \\code{.cpp}\n> + * utils::Duration d = 5s;\n> + * double d_in_ms = d.get<std::milli>();\n> + * \\endcode\n> + *\n> + * \\return The tick count of the Duration expressed in \\a Period\n> + */\n> +\n> +/**\n> + * \\fn Duration::operator bool()\n> + * \\brief Boolean operator to test if a \\a Duration holds a non-zero time value.\n> + *\n> + * \\return True if \\a Duration is a non-zero time value, False otherwise.\n> + */\n\nAll minor, which if not other comments, can be changed with your ack\nwhen applying\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\nThanks\n  j\n\n> +\n>  } /* namespace utils */\n>\n>  } /* namespace libcamera */\n> --\n> 2.25.1\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 4616FC3201\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 24 May 2021 11:58:08 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1306868919;\n\tMon, 24 May 2021 13:58:08 +0200 (CEST)","from relay12.mail.gandi.net (relay12.mail.gandi.net\n\t[217.70.178.232])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6C9A4601AA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 24 May 2021 13:58:07 +0200 (CEST)","(Authenticated sender: jacopo@jmondi.org)\n\tby relay12.mail.gandi.net (Postfix) with ESMTPSA id DF216200004;\n\tMon, 24 May 2021 11:58:06 +0000 (UTC)"],"Date":"Mon, 24 May 2021 13:58:52 +0200","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Naushir Patuck <naush@raspberrypi.com>","Message-ID":"<20210524115852.tea4nzfcd7v5tiel@uno.localdomain>","References":"<20210524084822.3690690-1-naush@raspberrypi.com>\n\t<20210524084822.3690690-2-naush@raspberrypi.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20210524084822.3690690-2-naush@raspberrypi.com>","Subject":"Re: [libcamera-devel] [PATCH v4 1/4] libcamera: utils: Add helper\n\tclass for std::chrono::duration","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","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":17197,"web_url":"https://patchwork.libcamera.org/comment/17197/","msgid":"<CAEmqJPo8m+UQpSzgXx5T1Z8J5aPcEg4_-gcW9TC_Dd8ckCHRKQ@mail.gmail.com>","date":"2021-05-24T12:30:20","subject":"Re: [libcamera-devel] [PATCH v4 1/4] libcamera: utils: Add helper\n\tclass for std::chrono::duration","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"Hi Jacopo,\n\nThank you for your review feedback.\n\nOn Mon, 24 May 2021 at 12:58, Jacopo Mondi <jacopo@jmondi.org> wrote:\n\n> Hi Naush,\n>\n> On Mon, May 24, 2021 at 09:48:19AM +0100, Naushir Patuck wrote:\n> > A new utils::Duration class is defined to represent a\n> > std::chrono::duration type with double precision nanosecond timebase.\n> > Using a double minimises the loss of precision when converting timebases.\n> > This helper class may be used by IPAs to represent variables such as\n> frame\n> > durations and exposure times.\n> >\n> > An operator << overload is define to help with displaying\n> > utils::Duration value in stream objects. Currently, this will display\n> > the duration value in microseconds.\n> >\n> > Signed-off-by: Naushir Patuck <naush@raspberrypi.com>\n> > Reviewed-by: David Plowman <david.plowman@raspberrypi.com>\n> > ---\n> >  include/libcamera/internal/utils.h | 42 ++++++++++++++++++++++++++++++\n> >  src/libcamera/utils.cpp            | 41 +++++++++++++++++++++++++++++\n> >  2 files changed, 83 insertions(+)\n> >\n> > diff --git a/include/libcamera/internal/utils.h\n> b/include/libcamera/internal/utils.h\n> > index 83dada7cc16c..f536f2267d70 100644\n> > --- a/include/libcamera/internal/utils.h\n> > +++ b/include/libcamera/internal/utils.h\n> > @@ -316,8 +316,50 @@ auto enumerate(T (&iterable)[N]) ->\n> details::enumerate_adapter<T *>\n> >  }\n> >  #endif\n> >\n> > +class Duration : public std::chrono::duration<double, std::nano>\n> > +{\n> > +     using BaseDuration = std::chrono::duration<double, std::nano>;\n> > +\n> > +public:\n> > +     Duration() = default;\n> > +\n> > +     template<typename Rep, typename Period>\n> > +     constexpr Duration(const std::chrono::duration<Rep, Period> &d)\n> > +             : BaseDuration(d)\n> > +     {\n> > +     }\n> > +\n> > +     template<typename Period>\n> > +     double get() const\n> > +     {\n> > +             auto const c =\n> std::chrono::duration_cast<std::chrono::duration<double, Period>>(*this);\n> > +             return c.count();\n> > +     }\n> > +\n> > +     explicit constexpr operator bool() const\n> > +     {\n> > +             return *this != BaseDuration::zero();\n> > +     }\n> > +};\n> > +\n> >  } /* namespace utils */\n> >\n> > +#ifndef __DOXYGEN__\n> > +template<class CharT, class Traits>\n> > +static inline std::basic_ostream<CharT, Traits>\n> &operator<<(std::basic_ostream<CharT, Traits> &os,\n> > +                                                         const\n> utils::Duration &d)\n> > +{\n> > +     std::basic_ostringstream<CharT, Traits> s;\n> > +\n> > +     s.flags(os.flags());\n> > +     s.imbue(os.getloc());\n> > +     s.setf(std::ios_base::fixed, std::ios_base::floatfield);\n> > +     s.precision(2);\n> > +     s << d.get<std::micro>() << \"us\";\n> > +     return os << s.str();\n> > +}\n> > +#endif\n> > +\n> >  } /* namespace libcamera */\n> >\n> >  #endif /* __LIBCAMERA_INTERNAL_UTILS_H__ */\n> > diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp\n> > index 826144d3c837..480284c6c2c9 100644\n> > --- a/src/libcamera/utils.cpp\n> > +++ b/src/libcamera/utils.cpp\n> > @@ -506,6 +506,47 @@ std::string libcameraSourcePath()\n> >   * loop, iterates over an indexed view of the \\a iterable\n> >   */\n> >\n> > +/**\n> > + * \\class Duration\n> > + * \\brief Helper class for std::chrono::duration types\n>\n> Helper class derived from std::chrono::duration that represents a time\n> duration in nanoseconds with double precision\n>\n\nAck.\n\n\n>\n> > + */\n> > +\n> > +/**\n> > + * \\typedef Duration::BaseDuration\n> > + * \\brief Base struct for the \\a Duration helper class\n> > + */\n>\n> Isn't this private ? does it need documentation ? It's just a\n> syntactic sugar used in the class definition, isn't it ?\n>\n\nIt is private/syntactic sugar - I was not sure what the rule was for\nprivate members with regards to documentation.  I can remove\nit.\n\n\n>\n>\n> > +\n> > +/**\n> > + * \\fn Duration::Duration(const std::chrono::duration<Rep, Period> &d)\n> > + * \\brief Copy constructor from a \\a std::chrono::duration type\n> > + * \\param[in] d The std::chrono::duration object to convert from\n> > + *\n> > + * Constructs a \\a Duration object from a \\a std::chrono::duration\n> object,\n> > + * internally converting the representation to \\a\n> Duration::BaseDuration type\n> > + */\n> > +\n> > +/**\n> > + * \\fn Duration::get<Period>()\n> > + * \\brief Retrieve the tick count, converted to the timebase provided\n> by the\n> > + * template argument Period of type \\a std::ratio\n> > + *\n> > + * A typical usage example is given below:\n> > + *\n> > + * \\code{.cpp}\n> > + * utils::Duration d = 5s;\n> > + * double d_in_ms = d.get<std::milli>();\n> > + * \\endcode\n> > + *\n> > + * \\return The tick count of the Duration expressed in \\a Period\n> > + */\n> > +\n> > +/**\n> > + * \\fn Duration::operator bool()\n> > + * \\brief Boolean operator to test if a \\a Duration holds a non-zero\n> time value.\n> > + *\n> > + * \\return True if \\a Duration is a non-zero time value, False\n> otherwise.\n> > + */\n>\n> All minor, which if not other comments, can be changed with your ack\n> when applying\n> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n>\n\nThank's for the tag.  I will submit a v5 revision with the updates once you\nand\nothers have a chance to comment on  all the other patches in the series.\n\nRegards,\nNaush\n\n\n>\n> Thanks\n>   j\n>\n> > +\n> >  } /* namespace utils */\n> >\n> >  } /* namespace libcamera */\n> > --\n> > 2.25.1\n> >\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 63E8DC3201\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 24 May 2021 12:30:39 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D82F268919;\n\tMon, 24 May 2021 14:30:38 +0200 (CEST)","from mail-lf1-x133.google.com (mail-lf1-x133.google.com\n\t[IPv6:2a00:1450:4864:20::133])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 2AFE0601AA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 24 May 2021 14:30:37 +0200 (CEST)","by mail-lf1-x133.google.com with SMTP id a2so40393328lfc.9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 24 May 2021 05:30:37 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"qymWP6Qi\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=pd4ML+r/1rYWHdg6I8n13yl0+DfMfqp7CdBWi6VwIAE=;\n\tb=qymWP6QinXUeI7WXlrV5rNE70X/nqg08oPURCcI9/JCxXPDrRgIISowXtULN7wC+DC\n\ttRhrbBZHRzOICo0AcQSbllyM39zpSxdqfBP/stYl8ISkageCf64MEPcOpXzemfTX/lC0\n\tb7iYbS+qV3kFpH61G38m1siHs4npQjOWaswJCZnETtYtklgUVhHHiBFg7mkCP7ByIwE4\n\t5JNCHac+X42nAqMkIGOoWC8+v2xaNcGMYBudSy9yr58SAQMJOshMYWo54MjBuDaWMwEk\n\tX2VlhHI2yKefMuM+TDqATLfgTA5sYez410jVUg4wdSXUAOuPK8a2V8oLiEJKJ+p8KAGn\n\tXtXQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=pd4ML+r/1rYWHdg6I8n13yl0+DfMfqp7CdBWi6VwIAE=;\n\tb=iPUPHCdgj8jOWXMjumWtv4GIQp3NFgraVjg1/fJohc//6qRjo2EL6YBX1xixaBf/od\n\tGtIXWBWISvF1BNTIQuAkuqqkS7GBuYJIFWbfQbMFAANWYCpkdsV7sHl1RiHnJtngMprJ\n\tYQmyoWxDqdQafeAo1l0MCzC56pBkT6PN9bY53pMMQ9z69y0SnrwFu23bIcW3dvRv/+OQ\n\tBw2fSmDA34tKORU/8gVEjbkfVm366+Z96H1uiFgVlC/ZG70Y5VgtjuwBYwWwJYRJZFBL\n\tA0xH7pLrk5klpKBmdBNQZh5PWtaYR98KmeXRiTQd04/cyNrzxrmHgqMN93rR2GnUY/Rx\n\txbAg==","X-Gm-Message-State":"AOAM532ngWsVjziORx9xWQBKgpXnzzv93gybmf/vC8ftrPVSGl7cUhIC\n\tGAZvVUVdkoxs6ojd1t4YY48LTOkJ/DWLhCcw9hWvmQ==","X-Google-Smtp-Source":"ABdhPJwLVdFU5+jylsbJ+9cpqv/hJbqAqvpEYNPjeudOshbzji88rprgTk1HW1P7H1tqETrSvMu2Dbni9dWTjRcAXkQ=","X-Received":"by 2002:a05:6512:10d4:: with SMTP id\n\tk20mr10145945lfg.210.1621859436376; \n\tMon, 24 May 2021 05:30:36 -0700 (PDT)","MIME-Version":"1.0","References":"<20210524084822.3690690-1-naush@raspberrypi.com>\n\t<20210524084822.3690690-2-naush@raspberrypi.com>\n\t<20210524115852.tea4nzfcd7v5tiel@uno.localdomain>","In-Reply-To":"<20210524115852.tea4nzfcd7v5tiel@uno.localdomain>","From":"Naushir Patuck <naush@raspberrypi.com>","Date":"Mon, 24 May 2021 13:30:20 +0100","Message-ID":"<CAEmqJPo8m+UQpSzgXx5T1Z8J5aPcEg4_-gcW9TC_Dd8ckCHRKQ@mail.gmail.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Content-Type":"multipart/alternative; boundary=\"00000000000094c9fd05c312938c\"","Subject":"Re: [libcamera-devel] [PATCH v4 1/4] libcamera: utils: Add helper\n\tclass for std::chrono::duration","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 <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":17198,"web_url":"https://patchwork.libcamera.org/comment/17198/","msgid":"<20210524124135.iqyph2vtsi525jzz@uno.localdomain>","date":"2021-05-24T12:41:35","subject":"Re: [libcamera-devel] [PATCH v4 1/4] libcamera: utils: Add helper\n\tclass for std::chrono::duration","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Naush,\n\nOn Mon, May 24, 2021 at 01:30:20PM +0100, Naushir Patuck wrote:\n> Hi Jacopo,\n>\n> Thank you for your review feedback.\n>\n> On Mon, 24 May 2021 at 12:58, Jacopo Mondi <jacopo@jmondi.org> wrote:\n>\n> > Hi Naush,\n> >\n> > On Mon, May 24, 2021 at 09:48:19AM +0100, Naushir Patuck wrote:\n> > > A new utils::Duration class is defined to represent a\n> > > std::chrono::duration type with double precision nanosecond timebase.\n> > > Using a double minimises the loss of precision when converting timebases.\n> > > This helper class may be used by IPAs to represent variables such as\n> > frame\n> > > durations and exposure times.\n> > >\n> > > An operator << overload is define to help with displaying\n> > > utils::Duration value in stream objects. Currently, this will display\n> > > the duration value in microseconds.\n> > >\n> > > Signed-off-by: Naushir Patuck <naush@raspberrypi.com>\n> > > Reviewed-by: David Plowman <david.plowman@raspberrypi.com>\n> > > ---\n> > >  include/libcamera/internal/utils.h | 42 ++++++++++++++++++++++++++++++\n> > >  src/libcamera/utils.cpp            | 41 +++++++++++++++++++++++++++++\n> > >  2 files changed, 83 insertions(+)\n> > >\n> > > diff --git a/include/libcamera/internal/utils.h\n> > b/include/libcamera/internal/utils.h\n> > > index 83dada7cc16c..f536f2267d70 100644\n> > > --- a/include/libcamera/internal/utils.h\n> > > +++ b/include/libcamera/internal/utils.h\n> > > @@ -316,8 +316,50 @@ auto enumerate(T (&iterable)[N]) ->\n> > details::enumerate_adapter<T *>\n> > >  }\n> > >  #endif\n> > >\n> > > +class Duration : public std::chrono::duration<double, std::nano>\n> > > +{\n> > > +     using BaseDuration = std::chrono::duration<double, std::nano>;\n> > > +\n> > > +public:\n> > > +     Duration() = default;\n> > > +\n> > > +     template<typename Rep, typename Period>\n> > > +     constexpr Duration(const std::chrono::duration<Rep, Period> &d)\n> > > +             : BaseDuration(d)\n> > > +     {\n> > > +     }\n> > > +\n> > > +     template<typename Period>\n> > > +     double get() const\n> > > +     {\n> > > +             auto const c =\n> > std::chrono::duration_cast<std::chrono::duration<double, Period>>(*this);\n> > > +             return c.count();\n> > > +     }\n> > > +\n> > > +     explicit constexpr operator bool() const\n> > > +     {\n> > > +             return *this != BaseDuration::zero();\n> > > +     }\n> > > +};\n> > > +\n> > >  } /* namespace utils */\n> > >\n> > > +#ifndef __DOXYGEN__\n> > > +template<class CharT, class Traits>\n> > > +static inline std::basic_ostream<CharT, Traits>\n> > &operator<<(std::basic_ostream<CharT, Traits> &os,\n> > > +                                                         const\n> > utils::Duration &d)\n> > > +{\n> > > +     std::basic_ostringstream<CharT, Traits> s;\n> > > +\n> > > +     s.flags(os.flags());\n> > > +     s.imbue(os.getloc());\n> > > +     s.setf(std::ios_base::fixed, std::ios_base::floatfield);\n> > > +     s.precision(2);\n> > > +     s << d.get<std::micro>() << \"us\";\n> > > +     return os << s.str();\n> > > +}\n> > > +#endif\n> > > +\n> > >  } /* namespace libcamera */\n> > >\n> > >  #endif /* __LIBCAMERA_INTERNAL_UTILS_H__ */\n> > > diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp\n> > > index 826144d3c837..480284c6c2c9 100644\n> > > --- a/src/libcamera/utils.cpp\n> > > +++ b/src/libcamera/utils.cpp\n> > > @@ -506,6 +506,47 @@ std::string libcameraSourcePath()\n> > >   * loop, iterates over an indexed view of the \\a iterable\n> > >   */\n> > >\n> > > +/**\n> > > + * \\class Duration\n> > > + * \\brief Helper class for std::chrono::duration types\n> >\n> > Helper class derived from std::chrono::duration that represents a time\n> > duration in nanoseconds with double precision\n> >\n>\n> Ack.\n>\n>\n> >\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\typedef Duration::BaseDuration\n> > > + * \\brief Base struct for the \\a Duration helper class\n> > > + */\n> >\n> > Isn't this private ? does it need documentation ? It's just a\n> > syntactic sugar used in the class definition, isn't it ?\n> >\n>\n> It is private/syntactic sugar - I was not sure what the rule was for\n> private members with regards to documentation.  I can remove\n> it.\n\nAs long as Doxygen does not complain, I think you can leave it out.\nHowever, I see you reference BaseDuration in other parts of the\ndocumentation\n\n>\n>\n> >\n> >\n> > > +\n> > > +/**\n> > > + * \\fn Duration::Duration(const std::chrono::duration<Rep, Period> &d)\n> > > + * \\brief Copy constructor from a \\a std::chrono::duration type\n> > > + * \\param[in] d The std::chrono::duration object to convert from\n> > > + *\n> > > + * Constructs a \\a Duration object from a \\a std::chrono::duration\n> > object,\n> > > + * internally converting the representation to \\a\n> > Duration::BaseDuration type\n\nhere\n\nIf this creates issue I think you could drop it here (or keep the\ndocumentation for BaseDuration, up to you :)\n\nThanks\n  j\n\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\fn Duration::get<Period>()\n> > > + * \\brief Retrieve the tick count, converted to the timebase provided\n> > by the\n> > > + * template argument Period of type \\a std::ratio\n> > > + *\n> > > + * A typical usage example is given below:\n> > > + *\n> > > + * \\code{.cpp}\n> > > + * utils::Duration d = 5s;\n> > > + * double d_in_ms = d.get<std::milli>();\n> > > + * \\endcode\n> > > + *\n> > > + * \\return The tick count of the Duration expressed in \\a Period\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\fn Duration::operator bool()\n> > > + * \\brief Boolean operator to test if a \\a Duration holds a non-zero\n> > time value.\n> > > + *\n> > > + * \\return True if \\a Duration is a non-zero time value, False\n> > otherwise.\n> > > + */\n> >\n> > All minor, which if not other comments, can be changed with your ack\n> > when applying\n> > Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n> >\n>\n> Thank's for the tag.  I will submit a v5 revision with the updates once you\n> and\n> others have a chance to comment on  all the other patches in the series.\n>\n> Regards,\n> Naush\n>\n>\n> >\n> > Thanks\n> >   j\n> >\n> > > +\n> > >  } /* namespace utils */\n> > >\n> > >  } /* namespace libcamera */\n> > > --\n> > > 2.25.1\n> > >\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 9C787C3200\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 24 May 2021 12:40:52 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E7EF568919;\n\tMon, 24 May 2021 14:40:51 +0200 (CEST)","from relay11.mail.gandi.net (relay11.mail.gandi.net\n\t[217.70.178.231])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 2FDA9601AA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 24 May 2021 14:40:50 +0200 (CEST)","(Authenticated sender: jacopo@jmondi.org)\n\tby relay11.mail.gandi.net (Postfix) with ESMTPSA id B9A98100008;\n\tMon, 24 May 2021 12:40:49 +0000 (UTC)"],"Date":"Mon, 24 May 2021 14:41:35 +0200","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Naushir Patuck <naush@raspberrypi.com>","Message-ID":"<20210524124135.iqyph2vtsi525jzz@uno.localdomain>","References":"<20210524084822.3690690-1-naush@raspberrypi.com>\n\t<20210524084822.3690690-2-naush@raspberrypi.com>\n\t<20210524115852.tea4nzfcd7v5tiel@uno.localdomain>\n\t<CAEmqJPo8m+UQpSzgXx5T1Z8J5aPcEg4_-gcW9TC_Dd8ckCHRKQ@mail.gmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<CAEmqJPo8m+UQpSzgXx5T1Z8J5aPcEg4_-gcW9TC_Dd8ckCHRKQ@mail.gmail.com>","Subject":"Re: [libcamera-devel] [PATCH v4 1/4] libcamera: utils: Add helper\n\tclass for std::chrono::duration","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 <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]