<commit_before>﻿/**
 * Sequential resource allocation and initialization is commonly encountered when working with C provided APIs.
 * In general multiple steps must be taken when aquiring and preparing a resource for use. A common usecase would
 * be to create e.g. an UDP socket for communication:
 *   First the socket must be created, then we may need to configure it using ioctl or other API calls. Perhaps
 *   we must also do a server name look-up too, or memory must be allocated for a buffer before we are ready to
 *   use the socket.
 * All of these steps in preparing the resource must be done in a more or less strict order. They can also fail at
 * any point and we must be ready to perform a full cleanup of the preceeding steps to avoid locking up any resources.
 *
 * Ultimately we want to check for success or failure at each step and upon failure we want to undo all the previous steps
 * in the reverse order. When we're done using the resource, cleanup should be run as well. Common implementations
 * often result in a convoluted, error-prone approach. Enter SequentialRaii.
 *
 * Through extensive use of lambda expressions it offers the following advantages:
 * - All the code for initializing and cleaning up a resource is localized in space and time. The code is also specified
 *   only once. This results in increased maintainability and significantly reduced possibility for bugs.
 * - Offers automatic cleanup in correct inverse order.
 *
 * Lambda expressions aren't without a disadvantage:
 * - As with any lambda use special care must be taken to manage the lifetime of any variables captured by reference.
 *   For example, the following code will generate a runtime exception since c's destructor is run before seqraii's
 *   when leaving the scope:
 *     {
 *       SequentialRaii seqraii;
 *       std::vector<int> c;
 *       seqraii.addStep([&](){c.push_back(1); return true;}, [&](){c.pop_back();});
 *       seqraii.initialize();
 *     }
 *   The modified code below will run just fine within the limits defined by C++:
 *     {
 *       std::vector<int> c;    // Swapped this line with the one below
 *       SequentialRaii seqraii;
 *       seqraii.addStep([&](){c.push_back(1); return true;}, [&](){c.pop_back();});
 *       seqraii.initialize();
 *     }
 *
 * Other information:
 *   Copyright 2015 <NAME>.
 *   License: MIT license. See separate file for full disclaimer.
 *   Compile with C++14 enabled.
 */
#pragma once

#include <vector>
#include <memory>

namespace sequentialraii
{
/**
 * Base class used for storing templated objects inside a vector.
 */
class StepBase
{
public:
    virtual ~StepBase() noexcept = default;

    virtual bool init() noexcept = 0;
    virtual void uninit() noexcept = 0;
};

// Forward declaration.
template <class Init, class Uninit> class Step;

/**
 * Container class for sequential raii steps.
 */
class SequentialRaii
{
public:
    /**<commit_msg>Removed README content from source code.<commit_after>﻿/**
 * Sequential resource allocation and initialization.
 * 
 * Copyright 2015 <NAME>.
 * License: MIT license. See separate file for full disclaimer.
 * Compile with C++14 enabled.
 */
#pragma once

#include <vector>
#include <memory>

namespace sequentialraii
{
/**
 * Base class used for storing templated objects inside a vector.
 */
class StepBase
{
public:
    virtual ~StepBase() noexcept = default;

    virtual bool init() noexcept = 0;
    virtual void uninit() noexcept = 0;
};

// Forward declaration.
template <class Init, class Uninit> class Step;

/**
 * Container class for sequential raii steps.
 */
class SequentialRaii
{
public:
    /**
{'fraction_non_alphanumeric': 0.08383561643835616, 'fraction_numerical': 0.004931506849315068, 'mean_word_length': 3.524163568773234, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1001219', 'n_tokens_mistral': 1000, 'n_tokens_neox': 961, 'n_words': 472}