Repository: bitcoin/bitcoin
File: src/script/script.h (C/C++)

Code before:

      return result;
    }

    int64_t m_value;
};

/**
 * We use a prevector for the script to reduce the considerable memory overhead
 *  of vectors in cases where they normally contain a small number of small elements.
 * Tests in October 2015 showed use of this reduced dbcache memory usage by 23%
 *  and made an initial sync 13% faster.
 */
typedef prevector<28, unsigned char> CScriptBase;

bool GetScriptOp(CScriptBase::const_iterator& pc, CScriptBase::const_iterator end, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet);

/** Serialized script, used inside transaction inputs and outputs */
class CScript : public CScriptBase
{
protected:
    CScript& push_int64(int64_t n)
    {
        if (n == -1 || (n >= 1 && n <= 16))
        {
            push_back(n + (OP_1 - 1));
        }
        else if (n == 0)
        {
            push_back(OP_0);
        }
        else
        {
            *this << CScriptNum::serialize(n);
        }
        return *this;
    }

public:
    CScript() = default;
    template <std::input_iterator InputIterator>
    CScript(InputIterator first, InputIterator last) : CScriptBase{first, last} { }

    SERIALIZE_METHODS(CScript, obj) { READWRITE(AsBase<CScriptBase>(obj)); }

    explicit CScript(int64_t b) { operator<<(b); }
    explicit CScript(opcodetype b)     { operator<<(b); }
    explicit CScript(const CScriptNum& b) { operator<<(b); }
    // delete non-existent constructor to defend against future introduction
    // e.g. via prevector
    explicit CScript(const std::vector<unsigned char>& b) = delete;

Review comment (refactor):
In commit "refactor: Make code more tolerant of constexpr std::arrays" (c4c102de7336e6c0cc2e5187feedf437ebadb565)

I'm not sure I see benefit of changing this from `unsigned char` to `uint8_t` now when there's a good chance this is going to be switched again to `std::byte` in the future. It could also be good eliminate the C cast on this line if it is changing anyway.

So not important, but would consider changing `uint8_t(size)` to `static_cast<value_type(size)>` here and changing `uint8_t` generally to `value_type` so this code can be unchanged if the surrounding code switches to `std::byte`.

Code after:
          return -((int64_t)(result & ~(0x80ULL << (8 * (vch.size() - 1)))));

      return result;
    }

    int64_t m_value;
};

/**
 * We use a prevector for the script to reduce the considerable memory overhead
 *  of vectors in cases where they normally contain a small number of small elements.
 * Tests in October 2015 showed use of this reduced dbcache memory usage by 23%
 *  and made an initial sync 13% faster.
 */
typedef prevector<28, unsigned char> CScriptBase;

bool GetScriptOp(CScriptBase::const_iterator& pc, CScriptBase::const_iterator end, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet);

/** Serialized script, used inside transaction inputs and outputs */
class CScript : public CScriptBase
{
private:
    inline void AppendDataSize(const uint32_t size)
    {
        if (size < OP_PUSHDATA1) {
            insert(end(), static_cast<value_type>(size));
        } else if (size <= 0xff) {
            insert(end(), OP_PUSHDATA1);
            insert(end(), static_cast<value_type>(size));
        } else if (size <= 0xffff) {
            insert(end(), OP_PUSHDATA2);
            value_type data[2];
            WriteLE16(data, size);
            insert(end(), std::cbegin(data), std::cend(data));
        } else {
            insert(end(), OP_PUSHDATA4);
            value_type data[4];
            WriteLE32(data, size);
            insert(end(), std::cbegin(data), std::cend(data));
        }
    }

    void AppendData(std::span<const value_type> data)
    {
        insert(end(), data.begin(), data.end());
    }

protected:
    CScript& push_int64(int64_t n)
    {
        if (n == -1 || (n >= 1 && n <= 16))