#include <iostream>
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>

using namespace boost::multi_index;

// Define a structure for the data
struct Book {
    int rank;
    std::string value;

    Book(int rank, const std::string& value) : rank(rank), value(value) {}
};

// Define tags to reference the indices
struct rank_tag {};

// Define a multi-index container for Book struct
typedef multi_index_container<
    Book,
    indexed_by<
        ordered_unique<
            tag<rank_tag>,    // Index by book rank
            member<Book, int, &Book::rank>
        >
    >
> BookMultiIndex;

// Function to insert a book and adjust ranks
void insert_book(BookMultiIndex& books, int rank, const std::string& value) {
    // Access by rank index
    auto& rank_index = books.get<rank_tag>();
    
    // Adjust ranks for books with rank >= the new rank
    for (auto it = rank_index.lower_bound(rank); it != rank_index.end(); ++it) {
        rank_index.modify(it, [](Book& b) {
            ++b.rank;
        });
    }

    // Insert the new book
    books.insert(Book(rank, value));
}

// Function to delete a book and adjust ranks
void delete_book(BookMultiIndex& books, int rank) {
    // Access by rank index
    auto& rank_index = books.get<rank_tag>();
    
    // Find the book to delete
    auto it = rank_index.find(rank);
    if (it != rank_index.end()) {
        // Erase the book
        rank_index.erase(it);

        // Adjust ranks for books with rank > the deleted rank
        for (auto it2 = rank_index.lower_bound(rank + 1); it2 != rank_index.end(); ++it2) {
            rank_index.modify(it2, [](Book& b) {
                --b.rank;
            });
        }
    }
}

// Function to print all elements
void print_all(const BookMultiIndex& books) {
    auto& rank_index = books.get<rank_tag>();
    std::cout << "Books in the container:" << std::endl;
    for (const auto& book : rank_index) {
        std::cout << "Rank = " << book.rank << ", Value = " << book.value << std::endl;
    }
}

int main() {
    // Create the multi-index container
    BookMultiIndex books;

    // Insert data into the container
    books.insert(Book(1, "a"));
    books.insert(Book(2, "b"));
    books.insert(Book(3, "c"));
    books.insert(Book(4, "d"));

    // Print initial state
    print_all(books);

    // Insert a new book at rank 2
    insert_book(books, 2, "f");
    std::cout << "\nAfter inserting at rank 2:" << std::endl;
    print_all(books);

    // Delete the book at rank 2
    delete_book(books, 2);
    std::cout << "\nAfter deleting rank 2:" << std::endl;
    print_all(books);

    return 0;
}
