summaryrefslogtreecommitdiff
path: root/graphs/cpp/my_nfts
diff options
context:
space:
mode:
Diffstat (limited to 'graphs/cpp/my_nfts')
-rw-r--r--graphs/cpp/my_nfts/auction.cc45
-rw-r--r--graphs/cpp/my_nfts/auction.hh34
-rw-r--r--graphs/cpp/my_nfts/main.cc37
-rw-r--r--graphs/cpp/my_nfts/nft.hh15
-rw-r--r--graphs/cpp/my_nfts/nft.hxx11
-rw-r--r--graphs/cpp/my_nfts/person.cc61
-rw-r--r--graphs/cpp/my_nfts/person.hh39
7 files changed, 242 insertions, 0 deletions
diff --git a/graphs/cpp/my_nfts/auction.cc b/graphs/cpp/my_nfts/auction.cc
new file mode 100644
index 0000000..534c61d
--- /dev/null
+++ b/graphs/cpp/my_nfts/auction.cc
@@ -0,0 +1,45 @@
+#include "auction.hh"
+
+#include <algorithm>
+Auction::Auction(Person& organizer, NFT nft, uint initial_bid)
+ : organizer_{ organizer }
+ , nft_{ std::move(nft) }
+ , highest_bidder_{ nullptr }
+ , highest_bid_{ initial_bid }
+{
+ if (!nft_ || nft_->empty())
+ throw std::invalid_argument{ "Invalid nft!" };
+}
+Auction::~Auction()
+{
+ if (highest_bidder_ == nullptr)
+ organizer_.add_nft(std::move(nft_));
+ else
+ {
+ highest_bidder_->add_nft(std::move(nft_));
+ organizer_.add_money(highest_bid_);
+ }
+}
+bool Auction::bid(Person& person, uint money)
+{
+ if (money > highest_bid_)
+ {
+ if (highest_bidder_ == nullptr)
+ highest_bidder_ = &person;
+ else
+ highest_bidder_->add_money(highest_bid_);
+ highest_bid_ = money;
+ highest_bidder_ = &person;
+ highest_bidder_->remove_money(money);
+ return true;
+ }
+ return false;
+}
+const std::string& Auction::get_nft_name() const
+{
+ return *nft_;
+}
+uint Auction::get_highest_bid() const
+{
+ return highest_bid_;
+} \ No newline at end of file
diff --git a/graphs/cpp/my_nfts/auction.hh b/graphs/cpp/my_nfts/auction.hh
new file mode 100644
index 0000000..9a1d162
--- /dev/null
+++ b/graphs/cpp/my_nfts/auction.hh
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "nft.hh"
+#include "person.hh"
+
+// Smart contract to auction a NFT.
+// It is a RAII class.
+class Auction
+{
+public:
+ // Start the auction with the given (non-null) NFT.
+ Auction(Person& organizer, NFT nft, uint initial_bid);
+ // Close the auction.
+ ~Auction();
+
+ // https://en.cppreference.com/w/cpp/language/rule_of_three#Rule_of_five
+ Auction(const Auction&&) = delete;
+ Auction(const Auction&) = delete;
+ Auction& operator=(const Auction&&) = delete;
+ Auction& operator=(const Auction&) = delete;
+
+ // Allow a person to bid at the auction.
+ bool bid(Person& person, uint money);
+
+ // Getters for the nft name and highest bid.
+ const std::string& get_nft_name() const;
+ uint get_highest_bid() const;
+
+private:
+ Person& organizer_;
+ NFT nft_;
+ Person* highest_bidder_;
+ uint highest_bid_;
+};
diff --git a/graphs/cpp/my_nfts/main.cc b/graphs/cpp/my_nfts/main.cc
new file mode 100644
index 0000000..2e9f462
--- /dev/null
+++ b/graphs/cpp/my_nfts/main.cc
@@ -0,0 +1,37 @@
+#include <iostream>
+
+#include "auction.hh"
+#include "person.hh"
+
+int main(void)
+{
+ auto p1 = Person("JP", 100);
+ auto p2 = Person("Claude", 50);
+
+ p1.add_nft(create_nft("Singe"));
+
+ std::cout << p1;
+ std::cout << p2;
+
+ p2.add_nft(p1.remove_nft("Singe"));
+
+ std::cout << p1;
+ std::cout << p2;
+
+ auto p3 = Person("Marie", 20);
+ std::cout << p1;
+ std::cout << p2;
+ std::cout << p3;
+
+ {
+ Auction auction(p2, p2.remove_nft("Singe"), 10);
+ std::cout << p1;
+ std::cout << p2;
+ std::cout << p3;
+
+ auction.bid(p1, 20);
+ }
+ std::cout << p1;
+ std::cout << p2;
+ std::cout << p3;
+}
diff --git a/graphs/cpp/my_nfts/nft.hh b/graphs/cpp/my_nfts/nft.hh
new file mode 100644
index 0000000..2147545
--- /dev/null
+++ b/graphs/cpp/my_nfts/nft.hh
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <memory>
+#include <string>
+
+// NFT declaration
+using NFT = std::unique_ptr<std::string>;
+
+// Create an empty NFT (convient in some scenarios).
+NFT create_empty_nft();
+// Create a NFT with the given name.
+NFT create_nft(const std::string& name);
+
+// Define the functions in the nft.hxx file.
+#include "nft.hxx"
diff --git a/graphs/cpp/my_nfts/nft.hxx b/graphs/cpp/my_nfts/nft.hxx
new file mode 100644
index 0000000..083f10f
--- /dev/null
+++ b/graphs/cpp/my_nfts/nft.hxx
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "nft.hh"
+inline NFT create_empty_nft()
+{
+ return nullptr;
+}
+inline NFT create_nft(const std::string& name)
+{
+ return std::make_unique<std::string>(name);
+} \ No newline at end of file
diff --git a/graphs/cpp/my_nfts/person.cc b/graphs/cpp/my_nfts/person.cc
new file mode 100644
index 0000000..cf4b291
--- /dev/null
+++ b/graphs/cpp/my_nfts/person.cc
@@ -0,0 +1,61 @@
+#include "person.hh"
+
+#include <algorithm>
+Person::Person(const std::string& name, uint money)
+ : name_{ name }
+ , money_{ money }
+{}
+std::vector<std::string> Person::enumerate_nfts() const
+{
+ std::vector<std::string> res;
+ for (auto nft = nfts_.begin(); nft != nfts_.end(); nft++)
+ {
+ res.push_back(**nft);
+ }
+ return res;
+}
+void Person::add_nft(NFT nft)
+{
+ nfts_.push_back(std::move(nft));
+}
+NFT Person::remove_nft(const std::string& name)
+{
+ auto pos = std::find_if(nfts_.begin(), nfts_.end(),
+ [&](NFT const& nft) { return *nft == name; });
+ if (pos == nfts_.end())
+ return create_empty_nft();
+ nfts_.erase(pos);
+ return create_nft(name);
+}
+void Person::add_money(uint money)
+{
+ money_ += money;
+}
+bool Person::remove_money(uint money)
+{
+ if (money > money_)
+ return false;
+ money_ -= money;
+ return true;
+}
+uint Person::get_money() const
+{
+ return money_;
+}
+const std::string& Person::get_name() const
+{
+ return name_;
+}
+std::ostream& operator<<(std::ostream& os, const Person& p)
+{
+ os << "Name: " << p.get_name() << "\nMoney: " << p.get_money() << "\nNFTs:";
+ if (const std::vector<std::string> nfts = p.enumerate_nfts(); !nfts.empty())
+ {
+ for (size_t i = 0; i < nfts.size(); ++i)
+ {
+ os << " " << nfts.at(i);
+ }
+ }
+ os << "\n";
+ return os;
+}
diff --git a/graphs/cpp/my_nfts/person.hh b/graphs/cpp/my_nfts/person.hh
new file mode 100644
index 0000000..90a2e16
--- /dev/null
+++ b/graphs/cpp/my_nfts/person.hh
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <ostream>
+#include <vector>
+
+#include "nft.hh"
+
+// A person
+class Person
+{
+public:
+ // Initiliaze its member attributes.
+ Person(const std::string& name, uint money);
+
+ // Returns the list of NFTs it owns.
+ std::vector<std::string> enumerate_nfts() const;
+
+ // Give it a NFT.
+ void add_nft(NFT nft);
+ // Take away a NFT.
+ NFT remove_nft(const std::string& name);
+
+ // Add money.
+ void add_money(uint money);
+ // Remove money, if possible.
+ bool remove_money(uint money);
+
+ // Getters for money and name.
+ uint get_money() const;
+ const std::string& get_name() const;
+
+private:
+ std::string name_;
+ uint money_;
+ std::vector<NFT> nfts_;
+};
+
+// Write informations about the person on the given stream.
+std::ostream& operator<<(std::ostream& os, const Person& p);