1919#ifndef LIBBITCOIN_SYSTEM_MACHINE_STACK_IPP
2020#define LIBBITCOIN_SYSTEM_MACHINE_STACK_IPP
2121
22- #include < tuple >
22+ #include < iterator >
2323#include < utility>
2424#include < bitcoin/system/data/data.hpp>
2525#include < bitcoin/system/define.hpp>
@@ -86,8 +86,6 @@ size() const NOEXCEPT
8686 return container_.size ();
8787}
8888
89- BC_PUSH_WARNING (NO_THROW_IN_NOEXCEPT)
90-
9189TEMPLATE
9290INLINE void CLASS::
9391push (data_chunk&& value) NOEXCEPT
@@ -130,8 +128,6 @@ emplace_chunk(const chunk_xptr& value) NOEXCEPT
130128 container_.emplace_back (value.get ());
131129}
132130
133- BC_POP_WARNING ()
134-
135131// Positional (stack cheats).
136132// ----------------------------------------------------------------------------
137133// These optimizations prevent used of std::stack.
@@ -180,9 +176,6 @@ peek(size_t index) const NOEXCEPT
180176 return *std::prev (container_.end (), add1 (index));
181177}
182178
183- // Aliases.
184- // ----------------------------------------------------------------------------
185-
186179TEMPLATE
187180INLINE bool CLASS::
188181peek_signed4 (int32_t & value) const NOEXCEPT
@@ -197,267 +190,6 @@ peek_signed5(int64_t& value) const NOEXCEPT
197190 return peek_signed<5 >(value);
198191}
199192
200- // / Variant data conversions.
201- // ----------------------------------------------------------------------------
202-
203- // Generalized integer peek for varying bit widths up to 8 bytes.
204- // Chunk to integer conversions are constrained by caller (4 or 5 bytes).
205- TEMPLATE
206- template <size_t Bytes, typename Integer,
207- if_not_lesser<sizeof (Integer), Bytes>,
208- if_signed_integral_integer<Integer>>
209- inline bool CLASS::
210- peek_signed (Integer& value) const NOEXCEPT
211- {
212- using namespace number ;
213- auto result{ true };
214-
215- std::visit (overload
216- {
217- [&](bool vary) NOEXCEPT
218- {
219- // This is never executed in standard scripts.
220- value = to_int (vary);
221- },
222- [&](int64_t vary) NOEXCEPT
223- {
224- // This is the canonical use case (bounds check only).
225- result = integer<Bytes>::from_integer (value, vary);
226- },
227- [&](const chunk_xptr& vary) NOEXCEPT
228- {
229- // This is never executed in standard scripts.
230- result = integer<Bytes>::from_chunk (value, *vary);
231- }
232- }, top ());
233-
234- return result;
235- }
236-
237- TEMPLATE
238- inline bool CLASS::
239- peek_bool () const NOEXCEPT
240- {
241- using namespace number ;
242- bool value{};
243-
244- std::visit (overload
245- {
246- [&](bool vary) NOEXCEPT
247- {
248- // This is the canonical use case.
249- value = vary;
250- },
251- [&](int64_t vary) NOEXCEPT
252- {
253- // This is never executed in standard scripts.
254- value = boolean::from_integer (vary);
255- },
256- [&](const chunk_xptr& vary) NOEXCEPT
257- {
258- // This is never executed in standard scripts.
259- value = boolean::from_chunk (*vary);
260- }
261- }, top ());
262-
263- return value;
264- }
265-
266- // Differs from peek_bool in that a chunk false must be empty [].
267- TEMPLATE
268- inline bool CLASS::
269- peek_strict_bool () const NOEXCEPT
270- {
271- using namespace number ;
272- bool value{};
273-
274- std::visit (overload
275- {
276- [&](bool vary) NOEXCEPT
277- {
278- // This is the canonical use case (after bip147).
279- value = vary;
280- },
281- [&](int64_t vary) NOEXCEPT
282- {
283- // This may be executed in standard scripts (before bip147).
284- value = boolean::from_integer (vary);
285- },
286- [&](const chunk_xptr& vary) NOEXCEPT
287- {
288- // This may be executed in standard scripts (before bip147).
289- value = boolean::from_chunk_strict (*vary);
290- }
291- }, top ());
292-
293- return value;
294- }
295-
296- // A chunk false must be [] and chunk true must be [0x01], otherwise fails.
297- TEMPLATE
298- inline bool CLASS::
299- peek_minimal_bool (bool & value) const NOEXCEPT
300- {
301- using namespace number ;
302- auto result{ true };
303-
304- std::visit (overload
305- {
306- [&](bool vary) NOEXCEPT
307- {
308- // This is the canonical use case (tapscript).
309- value = vary;
310- },
311- [&](int64_t vary) NOEXCEPT
312- {
313- // This may be executed in tapscripts (standard).
314- result = boolean::from_integer (value, vary);
315- },
316- [&](const chunk_xptr& vary) NOEXCEPT
317- {
318- // This may be executed in tapscripts (standard).
319- result = boolean::from_chunk (value, *vary);
320- }
321- }, top ());
322-
323- return result;
324- }
325-
326- // This is the only source of peek/pop (read) tethering.
327- TEMPLATE
328- inline chunk_xptr CLASS::
329- peek_chunk () const NOEXCEPT
330- {
331- using namespace number ;
332- chunk_xptr value{};
333-
334- std::visit (overload
335- {
336- [&](bool vary) NOEXCEPT
337- {
338- // This is never executed in standard scripts.
339- value = make_external (chunk::from_bool (vary), tether_);
340- },
341- [&](int64_t vary) NOEXCEPT
342- {
343- // This is never executed in standard scripts.
344- value = make_external (chunk::from_integer (vary), tether_);
345- },
346- [&](const chunk_xptr& vary) NOEXCEPT
347- {
348- // This is the canonical use case.
349- value = vary;
350- }
351- }, top ());
352-
353- return value;
354- }
355-
356- // Could use peek_chunk but this overload skips allocation and tethering.
357- TEMPLATE
358- inline size_t CLASS::
359- peek_size () const NOEXCEPT
360- {
361- using namespace number ;
362- size_t value{};
363-
364- std::visit (overload
365- {
366- [&](bool vary) NOEXCEPT
367- {
368- // This is never executed in standard scripts.
369- value = chunk::from_bool (vary).size ();
370- },
371- [&](int64_t vary) NOEXCEPT
372- {
373- // This is never executed in standard scripts.
374- value = chunk::from_integer (vary).size ();
375- },
376- [&](const chunk_xptr& vary) NOEXCEPT
377- {
378- // This is never executed in standard scripts.
379- value = vary->size ();
380- }
381- }, top ());
382-
383- return value;
384- }
385-
386- // / Static variant compare with conversion.
387- // / Integers are unconstrained as these are stack chunk equality comparisons.
388- TEMPLATE
389- inline bool CLASS::
390- equal_chunks (const stack_variant& left,
391- const stack_variant& right) NOEXCEPT
392- {
393- enum stack_type { bool_, int64_, pchunk_ };
394- static_assert (std::variant_size<stack_variant>::value == 3u );
395- const auto right_type = static_cast <stack_type>(right.index ());
396-
397- using namespace number ;
398- auto same{ true };
399-
400- // Methods bound at compile time (free).
401- // One runtime switch on variant index (cheap).
402- // bool/int conversions are compile-time (free).
403- // chunk conversions reduce to conventional bitcoin design.
404- std::visit (overload
405- {
406- // This is never executed in standard scripts.
407- [&](bool vary) NOEXCEPT
408- {
409- switch (right_type)
410- {
411- case bool_:
412- same = std::get<bool >(right) == vary;
413- break ;
414- case int64_:
415- same = std::get<int64_t >(right) == to_int (vary);
416- break ;
417- case pchunk_:
418- same = *std::get<chunk_xptr>(right) == chunk::from_bool (vary);
419- }
420- },
421-
422- // This is never executed in standard scripts.
423- [&](int64_t vary) NOEXCEPT
424- {
425- switch (right_type)
426- {
427- case bool_:
428- same = to_int (std::get<bool >(right)) == vary;
429- break ;
430- case int64_:
431- same = std::get<int64_t >(right) == vary;
432- break ;
433- case pchunk_:
434- same = *std::get<chunk_xptr>(right) == chunk::from_integer (vary);
435- }
436- },
437-
438- // This is the canonical use case.
439- [&](chunk_xptr vary) NOEXCEPT
440- {
441- switch (right_type)
442- {
443- case bool_:
444- // This is never executed in standard scripts.
445- same = chunk::from_bool (std::get<bool >(right)) == *vary;
446- break ;
447- case int64_:
448- // This is never executed in standard scripts.
449- same = chunk::from_integer (std::get<int64_t >(right)) == *vary;
450- break ;
451- case pchunk_:
452- // This is the canonical use case.
453- same = *std::get<chunk_xptr>(right) == *vary;
454- }
455- }
456- }, left);
457-
458- return same;
459- }
460-
461193} // namespace machine
462194} // namespace system
463195} // namespace libbitcoin
0 commit comments