1############################################################################
2#
3# Copyright (C) 2016 The Qt Company Ltd.
4# Contact: https://www.qt.io/licensing/
5#
6# This file is part of Qt Creator.
7#
8# Commercial License Usage
9# Licensees holding valid commercial Qt licenses may use this file in
10# accordance with the commercial license agreement provided with the
11# Software or, alternatively, in accordance with the terms contained in
12# a written agreement between you and The Qt Company. For licensing terms
13# and conditions see https://www.qt.io/terms-conditions. For further
14# information use the contact form at https://www.qt.io/contact-us.
15#
16# GNU General Public License Usage
17# Alternatively, this file may be used under the terms of the GNU
18# General Public License version 3 as published by the Free Software
19# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20# included in the packaging of this file. Please review the following
21# information to ensure the GNU General Public License requirements will
22# be met: https://www.gnu.org/licenses/gpl-3.0.html.
23#
24############################################################################
25
26from dumper import Children
27
28
29def qdump__boost__bimaps__bimap(d, value):
30    #leftType = value.type[0]
31    #rightType = value.type[1]
32    size = value["core"]["node_count"].integer()
33    d.putItemCount(size)
34    if d.isExpanded():
35        d.putPlainChildren(value)
36
37
38def qdump__boost__optional(d, value):
39    innerType = value.type[0]
40    (initialized, pad, payload) = d.split('b@{%s}' % innerType.name, value)
41    if initialized:
42        d.putItem(payload)
43        d.putBetterType(value.type)
44    else:
45        d.putSpecialValue("uninitialized")
46
47
48def qdump__boost__shared_ptr(d, value):
49    # s                  boost::shared_ptr<int>
50    #    px      0x0     int *
51    #    pn              boost::detail::shared_count
52    #        pi_ 0x0     boost::detail::sp_counted_base *
53    (px, pi) = value.split("pp")
54    if pi == 0:
55        d.putValue("(null)")
56        return
57
58    if px == 0:
59        d.putValue("(null)")
60        return
61
62    (vptr, usecount, weakcount) = d.split('pii', pi)
63    d.check(weakcount >= 0)
64    d.check(weakcount <= usecount)
65    d.check(usecount <= 10 * 1000 * 1000)
66    d.putItem(d.createValue(px, value.type[0]))
67    d.putBetterType(value.type)
68
69
70def qdump__boost__container__list(d, value):
71    r = value["members_"]["m_icont"]["data_"]["root_plus_size_"]
72    n = r["size_"].integer()
73    d.putItemCount(n)
74    if d.isExpanded():
75        innerType = value.type[0]
76        offset = 2 * d.ptrSize()
77        with Children(d, n):
78            try:
79                root = r["root_"]
80            except:
81                root = r["m_header"]
82            p = root["next_"].extractPointer()
83            for i in d.childRange():
84                d.putSubItem(i, d.createValue(p + offset, innerType))
85                p = d.extractPointer(p)
86
87
88def qdump__boost__gregorian__date(d, value):
89    d.putValue(value.integer(), "juliandate")
90
91
92def qdump__boost__posix_time__ptime(d, value):
93    ms = int(value.integer() / 1000)
94    d.putValue("%s/%s" % divmod(ms, 86400000), "juliandateandmillisecondssincemidnight")
95
96
97def qdump__boost__posix_time__time_duration(d, value):
98    d.putValue(int(value.integer() / 1000), "millisecondssincemidnight")
99
100
101def qdump__boost__unordered__unordered_set(d, value):
102    innerType = value.type[0]
103    if value.type.size() == 6 * d.ptrSize():  # 48 for boost 1.55+, 40 for 1.48
104        # boost 1.58 or 1.55
105        # bases are 3? bytes, and mlf is actually a float, but since
106        # its followed by size_t maxload, it's # effectively padded to a size_t
107        bases, bucketCount, size, mlf, maxload, buckets = value.split('tttttp')
108        # Distinguish 1.58 and 1.55. 1.58 used one template argument, 1.55 two.
109        try:
110            ittype = d.lookupType(value.type.name + '::iterator').target()
111            forward = len(ittype.templateArguments()) == 1
112        except:
113            forward = True
114    else:
115        # boost 1.48
116        # Values are stored before the next pointers. Determine the offset.
117        buckets, bucketCount, size, mlf, maxload = value.split('ptttt')
118        forward = False
119
120    if forward:
121        # boost 1.58
122        code = 'pp{%s}' % innerType.name
123
124        def children(p):
125            while True:
126                p, dummy, val = d.split(code, p)
127                yield val
128    else:
129        # boost 1.48 or 1.55
130        code = '{%s}@p' % innerType.name
131        (pp, ssize, fields) = d.describeStruct(code)
132        offset = fields[2].offset()
133
134        def children(p):
135            while True:
136                val, pad, p = d.split(code, p - offset)
137                yield val
138    p = d.extractPointer(buckets + bucketCount * d.ptrSize())
139    d.putItems(size, children(p), maxNumChild=10000)
140
141
142def qdump__boost__variant(d, value):
143    allTypes = value.type.templateArguments()
144    realType = allTypes[value.split('i')[0]]
145    alignment = max([t.alignment() for t in allTypes])
146    dummy, val = value.split('%is{%s}' % (max(4, alignment), realType.name))
147    d.putItem(val)
148    d.putBetterType(value.type)
149