repeat

nkrkv/text/repeat

Returns `N` copies of `IN` joined together.
repeat
@/repeat
Returns `N` copies of `IN` joined together.
INstring
Nnumber
The number of copies. Fractions are truncated. Negative values are interpreted as zero.
repeat
OUT
IN
N
OUTstring
To use the node in your project you should have the nkrkv/text library installed. Use the “File → Add Library” menu item in XOD IDE if you don’t have it yet. See Using libraries for more info.

C++ implementation

template<typename T> class RepeatView : public ListView<T> {
  public:
    class Cursor : public xod::detail::Cursor<T> {
      public:
        Cursor(const RepeatView* owner)
            : _iter(owner->_list.iterate())
            , _idx(0)
            , _owner(owner)
        {
        }

        bool isValid() const override {
            return _iter && isInRange();
        }

        bool value(T* out) const override {
            if (!isInRange())
                return false;
            return _iter.value(out);
        }

        void next() override {
            ++_iter;
            if (!_iter) {
                // one pass complete
                ++_idx;
                _iter = _owner->_list.iterate();
            }
        }

      private:
        bool isInRange() const {
            return _idx < _owner->_n;
        }

      private:
        const RepeatView* _owner;
        Iterator<T> _iter;
        size_t _idx;
    };

  public:
    RepeatView(List<T> list, int n)
        : _list(list)
        , _n(n)
    { }

    virtual Iterator<T> iterate() const override {
        return Iterator<T>(new Cursor(this));
    }

  private:
    friend class Cursor;
    List<T> _list;
    int _n;
};

struct State {
    uint8_t mem[sizeof(RepeatView<char>)];
};

{{ GENERATED_CODE }}

void evaluate(Context ctx) {
    auto state = getState(ctx);
    auto view = new (state->mem) RepeatView<char>(
        getValue<input_IN>(ctx),
        getValue<input_N>(ctx)
    );

    emitValue<output_OUT>(ctx, XString(view));
}