From 38dd90307ab2b0d25a0a233eae04455f769153b4 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 14 Jan 2020 21:37:27 +0200 Subject: libcamera: Remove std::piecewise_construct where not necessary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When inserting an element with emplace(), the element is constructed in-place with the parameters to the emplace() method being forwarded to the constructor of the element. For std::map containers, the element is an std::pair. The constructors of std::pair fall into three categories: (1) Default, copy and move constructors (and related versions) (2) Constructors that take lvalue or rvalue references to T1 and T2 (3) A forwarding constructor that forwards parameters to the constructors of T1 and T2 The first category isn't useful in most cases for std::map::emplace(), as the caller usually doesn't have an existing std::pair for the element to be inserted. The constructor from the third category is useful to avoid constructing intermediate Key or T instances when the caller doesn't have them available. This constructor takes two std::tuple arguments that contain the arguments for the Key and T constructors, respectively. Due to template deduction rules, usage of such a constructor couldn't be deduced by the compiler automatically in all cases, so the constructor takes a first argument of type std::piecewise_construct_t that lets the caller force the usage ot the forwarding constructor (also known for this reason as the piecewise constructor). The caller uses a construct such as map.emplace(std::piecewise_construct, std::forward_as_tuple(args_for_Key, ...), std::forward_as_tuple(args_for_T, ...)); This syntax is a bit heavy, but is required to construct Key and T in-place from arguments to their non-default constructor (it is also the only std::pair non-default constructor that can be used for non-copyable non-movable types). When the caller of std::map::emplace() already has references to a Key and a T, they can be passed to the std::pair piecewise constructor, and this will create std::tuple instance to wrap the Key and T references arguments to ultimately pass them to the Key and T copy constructors. map.emplace(std::piecewise_construct, std::forward_as_tuple(Key_value), std::forward_as_tuple(T_value)); While this mechanism works, it's unnecessary complex. A constructor of std::pair that takes references to Key and T can be used without any performance penalty, as it will also call the copy constructor of Key and T. In this case we can use a simpler constructor of std::pair, and thus a simpler call of std::map::emplace. map.emplace(Key_value, T_value); We have a couple occurrences of this above misuse of piecewise construction. Simplify them, which simplifies the code and reduces the generated code size. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Reviewed-by: Kieran Bingham --- src/libcamera/pipeline/uvcvideo.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/libcamera/pipeline/uvcvideo.cpp') diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 83093676..29afb121 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -365,9 +365,7 @@ int UVCCameraData::init(MediaEntity *entity) continue; } - ctrls.emplace(std::piecewise_construct, - std::forward_as_tuple(id), - std::forward_as_tuple(range)); + ctrls.emplace(id, range); } controlInfo_ = std::move(ctrls); -- cgit v1.2.1