File: nsCycleCollectionContainerParticipant.h

package info (click to toggle)
firefox 147.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,683,324 kB
  • sloc: cpp: 7,607,156; javascript: 6,532,492; ansic: 3,775,158; python: 1,415,368; xml: 634,556; asm: 438,949; java: 186,241; sh: 62,751; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (60 lines) | stat: -rw-r--r-- 3,039 bytes parent folder | download | duplicates (13)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef nsCycleCollectionContainerParticipant_h__
#define nsCycleCollectionContainerParticipant_h__

#include <type_traits>

/*
 * To be able to implement ImplCycleCollectionIndexedContainer, we need to
 * handle const vs non-const. ImplCycleCollectionTrace requires that the the
 * value traced is non-const, and historically ImplCycleCollectionTraverse has
 * been declared to take either const or non-const values. This poses a problem
 * for containers, since it's not possible to define one
 * ImplCycleCollectionIndexedContainer for both the const and non-const case
 * with a templated parameter for the type contained by the container. The
 * reason for this is how overload resolution works when it sees non-generic
 * types with different constness. The standard solution for this is to use a
 * universal reference, but we can't do this only because suddenly our
 * ImplCycleCollectionIndexedContainer would be valid for any type. To make this
 * work we need a way to constrain the type and we need it to be a constraint on
 * the container type, not the type contained.
 *
 * This is pretty much the proposal for std::is_specialization_of, but with
 * names from the unofficial cycle collector namespace. We use this to be able
 * to do partial specialization to overload containers whose contents we wish to
 * have participate in cycle collection. `template <typename Container>
 * EnableCycleCollectionIf<Container, SomeContainer>` allows us to restrict an
 * overload to only happen for a type SomeContainer<T>, which we then can use to
 * make sure that an ImplCycleCollectionIndexedContainer overload is for a
 * particular container, const or not.
 *
 * Example:
 *
 * template <typename Container, typename Callback,
 *           EnableCycleCollectionIf<Container, nsTHashtable> = nullptr>
 * inline void ImplCycleCollectionContainer(Container&& aField,
 *                                          Callback&& aCallback) {
 *   // Implementation goes here
 * }
 */
template <typename, template <typename...> typename>
struct ImplCycleCollectionIsContainerT : std::false_type {};

template <template <typename...> typename Container, typename... Args>
struct ImplCycleCollectionIsContainerT<Container<Args...>, Container>
    : std::true_type {};

template <typename T, template <typename...> typename Container>
constexpr bool ImplCycleCollectionIsContainer = ImplCycleCollectionIsContainerT<
    std::remove_cv_t<std::remove_reference_t<T>>, Container>::value;

template <typename T, template <typename...> typename Container>
using EnableCycleCollectionIf =
    typename std::enable_if_t<ImplCycleCollectionIsContainer<T, Container>>*;

#endif  // nsCycleCollectionContainerParticipant_h__