C++ Program with Pointers

 

The program reads data from two files, itemsList-0x.txt and inventoryList-0x.txt. File extensions on Linux may be arbitrary–i.e., these files could have been named with .dat as the extensions.

Don't use plagiarized sources. Get Your Custom Essay on
C++ Program with Pointers
Just from $13/Page
Order Essay

The first file, itemsList-0x.txt, lists all possible items. Each line represents one item in the form id name.

Example 1: Sample itemsList-0x.txt0 Air 1 HP Potion 2 MP Potion 5 Iron Ore 3 Bow Tie 4 Dirt 6 Diamond Ore 7 Iron Ingot 8 Diamond 9 Diamond Block 

The second file, inventoryList-0x.txt, lists each individual inventory–or storage chest–followed by a list of items.

Example 2: Sample inventoryList-0x.txt# 5 – 1 10 – 2  5 – 3  2 # 6 – 4  3 – 5 27 – 6 44 – 7 55 – 8  1 – 9  4 – 4  3 # 2 – 2  5 – 9  4 – 8  1 – 5  2 – 10 5 

Each line preceded by # denotes the start of a new inventory. Each line preceded by – denotes an item. The program creates a new inventory each time a # is encountered.

When a – is encountered, a stack of items, ItemStack, is created. The ItemStack is placed in the Inventory based on the following rules:

  1. If the Inventory is empty, store the ItemStack, and return true.
  2. If the Inventory is not empty, examine the Inventory.

    If a matching ItemStack is found, merge the two ItemStacks and return true.
    If no matching ItemStack is found, store the new ItemStack and return true.

  3. If the Inventory is full, return false.

Through the magic of abstraction, this is not one function, but four (4) functions in total. Yes, it does seem unnecessary at first. However, each function does one thing and only one thing. This is an exercise in understanding the thought process behind abstraction, interfaces, and the S/O in S.O.L.I.D (with some C++ code) in a multi-ADT program.

Most of your time will be spent on understanding the abstractions (and interfaces) as opposed to spamming cobblestone blocks… I mean C++ code.

3.2 Output

The output consists of three reports written to standard output, one after the other.

  1. A report listing items that were stored or discarded.
  2. A report listing all valid items.
  3. Finally, a detailed report is printed. listing data for each inventory:

    Maximum Capacity–i.e., total slots.
    Utilized Capacity–i.e., occupied slots
    Listing of all items.

If the program is run with the provided input files, the following output should be generated…

Example 3: Sample OutputProcessing Log:  Stored (10) HP Potion  Stored ( 5) MP Potion  Stored ( 2) Bow Tie  Stored ( 3) Dirt  Stored (27) Iron Ore  Stored (44) Diamond Ore  Stored (55) Iron Ingot  Stored ( 1) Diamond  Stored ( 4) Diamond Block  Stored ( 3) Dirt  Stored ( 5) MP Potion  Stored ( 4) Diamond Block  Discarded ( 1) Diamond  Discarded ( 2) Iron Ore  Item List:    0 Air    1 HP Potion    2 MP Potion    3 Bow Tie    4 Dirt    5 Iron Ore    6 Diamond Ore    7 Iron Ingot    8 Diamond    9 Diamond Block  Storage Summary:  -Used 3 of 5 slots   (10) HP Potion   ( 5) MP Potion   ( 2) Bow Tie   -Used 6 of 6 slots   ( 6) Dirt   (27) Iron Ore   (44) Diamond Ore   (55) Iron Ingot   ( 1) Diamond   ( 4) Diamond Block   -Used 2 of 2 slots   ( 5) MP Potion   ( 4) Diamond Block  

3.3 Running the Program

The easiest way to see generate the expected output is to run the sample executable solution I have provided. These two files are named as command-line parameters when the program is executed.

For example, if the sample data

above

is kept in files itemList-01.txt and inventoryList-01.txt, then to run this program, do:

./storage itemList-01.txt inventoryList-01.txt

(On a Windows system, you would omit the “./”. If you are running from Code::Blocks or a similar development environment, you may need to review how to

supply command-line parameters

to a running program.)

4 Your Tasks

One of the most important skills in our craft is interpreting error messages. Remember the ones you receive when you attempt to compile and run the unmodified code.

The key abstractions employed in this program are Item, ItemStack, and Inventory. Complete ADT implementations have been provided for Item and Inventory.

A partial implementation has been provided for the ItemStack. Your task is to finish the update ItemStack ADT.

This assignment is smaller than the previous two (in terms of code and number of new concepts). Most of your time will be spent reviewing the basics of pointers. Spend the time reviewing. Practice with pointers. You will need to use pointers (in one form or another) for the reminder of the semester.

You must implement the:

  1. Copy Constructor
  2. Destructor
  3. Assignment Operator

    Note this is already provided and complete. Refer to our discussions of the copy-and-

  4. swap
  5. method.
    Once you have completed the Copy Constructor, Destructor, and swap you are done with the Big-3.

  6. Logical Equivalence (i.e., operator==).
  7. Less-Than (i.e., operator<).
  8. swap

Refer to the comments in each function for additional detail.

Employ your Head-to-Head Testing Skills from CS 250.

4.1 Three Main Functions?

As you look through the provided code, you will find three main functions: one in storage.cpp (as expected), one in TestInventory.cpp, and one in TestItemStack.cpp. If you are creating a project in your IDE do not include both in your project settings. You will need to either create multiple targets in your project settings, or rely on the makefile.

You should probably run the tests on a Linux machine… You can compile the main program (storage) and test drivers (testInventory and testItemStack) with

make

Take note of the semicolon (;) after testInventory. This is a standard Linux trick to run two commands back-to-back.

You can then run storage as described above. You can run the Inventory and ItemStack test drivers with:

./testInventory; ./testItemStack

If you implemented everything correctly you will see:

Inventory:
 PASSED -> testDefaultConstructor
 PASSED -> testConstructorSizeN
 PASSED -> testAddItemStackNoCheck
 PASSED -> testAddItemWithDuplicateItems
 PASSED -> testAddItemAfterFull
 PASSED -> testCopyConstructorForEmpty
 PASSED -> testCopyConstructor
 PASSED -> testAssignmentOperator
 PASSED -> testDisplay
ItemStack:
 PASSED -> testDefaultConstructor
 PASSED -> testSecondConstructor
 PASSED -> testCopyConstructor
 PASSED -> testAssignment
 PASSED -> testAddItems
 PASSED -> testAddItemsFrom
 PASSED -> testLogicalEquivalence
 PASSED -> testLessThan
 PASSED -> testDisplay
 PASSED -> testSwap

If you see FAILED you must revisit revisit the corresponding function(s). There is a mistake somewhere in your code. Where should you look? Pay close attention to the line immediately before FAILED… use that as a starting point.

Remember to ask questions if you get stuck.

4.1.1 Segmentation Faults & Getting Started

Since ItemStack’s item data member is a pointer

Item* item;

segmentation faults are a consideration. If you download, compile and run the tests, without implementing anything, you will receive test output similar to:

Inventory:
 PASSED -> testDefaultConstructor
 PASSED -> testConstructorSizeN
[1]    21524 segmentation fault (core dumped)  ./testInventory
ItemStack:
[1]    21526 segmentation fault (core dumped)  ./testItemStack

Here is a free hint. Go to the Copy Constructor and add

   this->item = src.item->clone();

This line will create a deep copy of src.item. Once you have made that one-line addition, recompile everything and run

./testInventory; ./testItemStack

again. You should see:

Inventory:
 PASSED -> testDefaultConstructor
 PASSED -> testConstructorSizeN
FAILURE: testAddItemStackNoCheck:89 -> (*(it++) == stacksToAdd[0])
 FAILED -> testAddItemStackNoCheck
FAILURE: testAddItemWithDuplicateItems:126 -> (*(it++) == stacksToAdd[0])
 FAILED -> testAddItemWithDuplicateItems
FAILURE: testAddItemAfterFull:172 -> (*(it++) == stacksToAdd[0])
 FAILED -> testAddItemAfterFull
 PASSED -> testCopyConstructorForEmpty
FAILURE: testCopyConstructor:268 -> (aCopy == source)
 FAILED -> testCopyConstructor
FAILURE: testAssignmentOperator:305 -> (aCopy == source)
 FAILED -> testAssignmentOperator
FAILURE: testDisplay:204 -> (bagString.find(stacksAsStrings[0]) != std::string::npos)
 FAILED -> testDisplay
ItemStack:
 PASSED -> testDefaultConstructor
 PASSED -> testSecondConstructor
FAILURE: testCopyConstructor:70 -> (aCopy.size() == 9002)
 FAILED -> testCopyConstructor
FAILURE: testAssignment:91 -> (aCopy.size() == 9002)
 FAILED -> testAssignment
 PASSED -> testAddItems
 PASSED -> testAddItemsFrom
FAILURE: testLogicalEquivalence:142 -> (stack1 == stack2)
 FAILED -> testLogicalEquivalence
FAILURE: testLessThan:164 -> (stack3 < stack1)  FAILED -> testLessThan
 PASSED -> testDisplay
FAILURE: testSwap:198 -> (stack1.getItem().getName() == “Ice”)
 FAILED -> testSwap

There is nothing wrong with Inventory. Inventory is dependent on ItemStack. Until ItemStack is complete you will see failures in testInventory.

Pointers/bodgeUnitTest.h
#ifndef BODGE_UNIT_TEST_H_INCLUDED
#define BODGE_UNIT_TEST_H_INCLUDED
#include
#include
#include
#include
#include “utilities.h”
#include “bodgeUnitTest.h”
/**
* This is the Bodge-Unit-Testing… PseUdO-Framework
*
* Bodge – A clumsy or inelegant job, usually a temporary repair;
* a patch, a repair. (From Wiktionary)
*/
#define bodgeAssert(expression) \
if (!(expression)) { \
std::cout << "FAILURE: "\ << __func__ << ":" << __LINE__\ << " -> (” << #expression << ")\n";\ return false;\ } // End Macro // Unit Aliases using UnitTestFunction = std::function;
using UnitTestPair = std::pair;
/**
* Run a single unit test function and output PASSED of FAILED based on the
* result.
*
* @TODO I could (and should) probably turn this into a macro.
*/
inline
void runTest(const UnitTestFunction& testFunction, std::string description)
{
std::cout << " " << (testFunction() ? "PASSED" : "FAILED") << " -> ” << description << std::endl; } #endif Pointers/CPPLINT.cfg linelength=80 filter=-legal/copyright filter=-readability/namespace filter=-build/header_guard filter=-whitespace/indent filter=-whitespace/braces filter=-whitespace/blank_line filter=-build/namespaces filter=-readability/braces filter=-whitespace/newline filter=-build/include_subdir filter=-runtime/references filter=-runtime/threadsafe_fn filter=-runtime/int filter=-runtime/explicit filter=-whitespace/ending_newline filter=-runtime/string # Too many false positives filter=-build/include Pointers/Inventory.cpp #include
#include
#include “Inventory.h”
// Allow the compiler to define the remaining
// comparison operators
using namespace std::rel_ops;
//——————————————————————————
Inventory::Inventory()
:Inventory(10)
{
}
//——————————————————————————
Inventory::Inventory(int n)
:slots(n)
{
}
//——————————————————————————
Inventory::Inventory(const Inventory& src)
{
this->slots = src.slots;
this->allItemStacks.reserve(this->slots);
std::copy(src.begin(), src.end(), std::back_inserter(this->allItemStacks));
}
//——————————————————————————
int Inventory::utilizedSlots() const
{
return allItemStacks.size();
}
//——————————————————————————
int Inventory::emptySlots() const
{
return totalSlots() – utilizedSlots();
}
//——————————————————————————
int Inventory::totalSlots() const
{
return slots;
}
//——————————————————————————
bool Inventory::isFull() const
{
return emptySlots() == 0;
}
//——————————————————————————
bool Inventory::addItems(ItemStack itemStack)
{
const int& targetId = itemStack.getItem().getID();
auto id_equal_function = [targetId](const ItemStack& aStack)
{
return aStack.getItem().getID() == targetId;
};
auto matchingIterator = std::find_if(this->begin(),
this->end(),
id_equal_function);
// A match was found
if (matchingIterator != this->end()){
ItemStack& stackToUpdate = *matchingIterator;
stackToUpdate.addItemsFrom(itemStack);
return true;
}
// There is no space for a new type of `ItemStack`
if (this->isFull()) {
return false;
}
// This is a new type of item and there is plenty of room
allItemStacks.push_back(itemStack);
return true;
}
//——————————————————————————
Inventory::iterator Inventory::begin()
{
return allItemStacks.begin();
}
//——————————————————————————
Inventory::iterator Inventory::end()
{
return allItemStacks.end();
}
//——————————————————————————
Inventory::const_iterator Inventory::begin() const
{
return allItemStacks.begin();
}
//——————————————————————————
Inventory::const_iterator Inventory::end() const
{
return allItemStacks.end();
}
//——————————————————————————
void Inventory::display(std::ostream &outs) const
{
outs << " -Used " << utilizedSlots() << " of " << slots << " slots" << "\n"; for (const ItemStack& it : *this) { outs << " " << it << "\n"; } } //------------------------------------------------------------------------------ Inventory& Inventory::operator=(Inventory rhs) { std::swap(*this, rhs); return *this; } //------------------------------------------------------------------------------ void Inventory::swap(Inventory& other) { using std::swap; Inventory& lhs = *this; Inventory& rhs = other; swap(lhs.allItemStacks, rhs.allItemStacks); swap(lhs.slots, rhs.slots); } //------------------------------------------------------------------------------ bool operator==(const Inventory& lhs, const Inventory& rhs) { if (lhs.utilizedSlots() != rhs.utilizedSlots()) { return false; } if (lhs.totalSlots() != rhs.totalSlots()) { return false; } return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } //------------------------------------------------------------------------------ // This function is missing. While you do not have to write it... you need to // be able to explain: // // 1. Why the program still works without operator< // 2. Why not including operator< *can* lead to issues // // bool operator<(const Inventory& lhs, const Inventory& rhs) Pointers/Inventory.h #ifndef INVENTORY_H_INCLUDED #define INVENTORY_H_INCLUDED #include
#include
#include “ItemStack.h”
/**
* An Inventory is composed of n slots. Each slot may store only
* one type of item–specified by *slots*.
*

* Once all slots are filled, no additional Item types may be stored.
* Individual slots may contain any number of the same
* Item.
*/
class Inventory {
public:
/**
* Alias for a container of ItemStacks.
*/
using ItemStackCollection = std::vector;
using iterator = ItemStackCollection::iterator;
using const_iterator = ItemStackCollection::const_iterator;
private:
/**
* All `ItemStack`s in *this* `Inventory`
*/
ItemStackCollection allItemStacks;
/**
* Total capacity of *this* `Inventory`.
*/
int slots;
public:
/**
* Default to 10 slots
*/
Inventory();
/**
* Create an inventory.
*
* @param n total slots (capacity)
*
* @pre n > 0
*/
Inventory(int n);
/**
* Duplicate an existing Inventory
*
* @param src existing Inventory.
*/
Inventory(const Inventory& src);
/**
* Empty all Inventory slots.
*
* Let the compiler do all the work;
*/
~Inventory() = default;
/**
* Check the number of used/utilized (i.e., non-empty).
*/
int utilizedSlots() const;
/**
* Check the number of unused (i.e., empty) slots.
*/
int emptySlots() const;
/**
* Retrieve the total size (number of slots in total).
*/
int totalSlots() const;
/**
* Check if this inventory is full
*
* @return true if all slots are filled and false otherwise
*/
bool isFull() const;
/**
* Add one or more items to the inventory list
*
* @return true if *stack* was added and false otherwise
*/
bool addItems(ItemStack itemStack);
/**
* Print a Summary of the Inventory and all Items contained within
*/
void display(std::ostream& outs) const;
// Begin Iterator Support (begin/end)
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
// End Iterator Support
/**
* Assignment operator (implemented using the copy-and-swap trick).
*/
Inventory& operator=(Inventory rhs);
/**
* Swap the contents of *this* and another inventory.
*/
void swap(Inventory& other);
};
/**
* Print the Inventory through use of the display member function
*/
inline
std::ostream& operator<<(std::ostream& outs, const Inventory& prt) { prt.display(outs); return outs; } /** * Compare two Inventory objects, without direct access */ bool operator==(const Inventory& lhs, const Inventory& rhs); /** * Swap the contents of two inventories. This is a wrapper around the swap * member function. * * @param lhs first inventory (left hand side) * @param rhs second inventory (right hand side) */ inline void swap(Inventory& lhs, Inventory& rhs) { lhs.swap(rhs); } #endif Pointers/inventoryList-00.txt # 3 - 1 10 - 2 5 - 3 2 # 6 - 4 3 - 5 27 - 6 44 - 7 55 - 8 1 - 9 4 - 4 3 # 5 - 2 5 - 9 4 - 8 1 - 5 2 - 7 5 Pointers/inventoryList-01.txt # 5 - 1 10 - 2 5 - 3 2 # 6 - 4 3 - 5 27 - 6 44 - 7 55 - 8 1 - 9 4 - 4 3 # 2 - 2 5 - 9 4 - 8 1 - 5 2 - 10 5 Pointers/inventoryList-02.txt # 2 - 1 10 - 57 1 - 57 4 # 3 - 4 3 - 13 27 - 13 44 - 17 55 - 17 1 - 19 4 - 42 3 # 2 - 41 5 - 49 4 - 49 1 - 264 2 - 33 5 Pointers/inventoryList-03.txt # 2 - 1 10 - 57 1 - 57 4 # 3 - 4 3 - 13 27 - 13 44 - 17 55 - 17 1 - 19 4 - 42 3 # 2 Pointers/Item.cpp #include
#include “Item.h”
#include “utilities.h”
//——————————————————————————
Item::Item()
:Item(0, “Air”)
{
}
//——————————————————————————
Item::Item(int i, std::string n)
:id(i),
name(n)
{
}
//——————————————————————————
bool Item::operator==(const Item &rhs) const
{
return this->id == rhs.id;
}
//——————————————————————————
bool Item::operator<(const Item &rhs) const { return this->id < rhs.id; } //------------------------------------------------------------------------------ void Item::display(std::ostream &outs) const { outs << std::right << std::setw(3) << id << " " << name; } //------------------------------------------------------------------------------ void Item::read(std::istream& ins) { // Use temp vars in case something goes wrong... int i = 0; std::string n("Air"); ins >> i;
getline(ins, n);
trim(n);
this->setID(i);
this->setName(n);
}

Pointers/Item.h
#ifndef ITEM_H_INCLUDED
#define ITEM_H_INCLUDED
#include
#include
/**
* Item represents an individual Item in an inventory.
* This includes items such as potions, building materials, and food.
*
* Only one of each item can exist–i.e., no two items share the
* same numeric id.
*/
class Item {
private:
int id; ///< Unique numeric identifier--e.g., 1 std::string name; ///< Short title--e.g., HP Potion public: /** * Default to id = 0 and name = Air */ Item(); /** * Create an Item with a specified id and name * * @param i desired id * @param n desired name * * @pre * - all items that share an id are of the same type * - id is strictly positive */ Item(int i, std::string n); // The compiler can handle the Big-3 Item(const Item& src) = default; ~Item() = default; Item& operator=(const Item& rhs) = default; /** * Retrieve numeric id */ int getID() const; /** * Update numeric id * * @pre i is strictly positive */ void setID(int i); /** * Retrieve name */ std::string getName() const; /** * Update name */ void setName(std::string n); /** * Wrapper around copy constructor */ Item* clone() const; /** * Check for logical equivalence--based on numeric id */ bool operator==(const Item &rhs) const; /** * Check ordering--based on numeric id */ bool operator<(const Item &rhs) const; /** * Print one Item */ void display(std::ostream &outs) const; /** * Read in an update Item id and name */ void read(std::istream& ins); }; /** * Print one Item by invoking display. */ inline std::ostream& operator<<(std::ostream &outs, const Item &prt) { prt.display(outs); return outs; } /** * Read in one Item by invoking read. */ inline std::istream& operator>>(std::istream& ins, Item& toRead)
{
toRead.read(ins);
return ins;
}
//——————————————————————————
inline
int Item::getID() const
{
return this->id;
}
//——————————————————————————
inline
void Item::setID(int i)
{
this->id = i;
}
//——————————————————————————
inline
std::string Item::getName() const
{
return this->name;
}
//——————————————————————————
inline
void Item::setName(std::string n)
{
this->name = n;
}
//——————————————————————————
inline
Item* Item::clone() const
{
return new Item(*this);
}
#endif

Pointers/itemList-00.txt
0 Air
1 HP Potion
2 MP Potion
5 Iron Ore
3 Bow Tie
4 Dirt
6 Diamond Ore
7 Iron Ingot
8 Diamond
9 Diamond Block

Pointers/itemList-01.txt
0 Air
1 HP Potion
2 MP Potion
5 Iron Ore
3 Bow Tie
4 Dirt
6 Diamond Ore
7 Iron Ingot
8 Diamond
9 Diamond Block

Pointers/itemList-02.txt
0 Air
1 Stone
2 Grass
3 Dirt
4 Cobblestone
13 Gravel
14 Gold Ore
15 Iron Ore
16 Coal Ore
17 Oak Wood
19 Sponge
33 Piston
41 Gold Block
42 Iron Block
49 Obsidian
50 Torch
56 Diamond Ore
57 Diamond Block
73 Redstone Ore
264 Diamond

Pointers/ItemStack.cpp
#include
#include “ItemStack.h”

const Item ItemStack::DEFAULT_ITEM(0, “Air”);

//——————————————————————————
ItemStack::ItemStack()
:ItemStack(DEFAULT_ITEM, 0)
{
}
//——————————————————————————
ItemStack::ItemStack(const Item& inputItem, int s)
:quantity(s)
{
// Create a copy (clone) of inputItem and reference it with the this->item
// pointer
this->item = inputItem.clone();
}
//——————————————————————————
ItemStack::ItemStack(const ItemStack& src)
{
// 1 . Create a copy (clone) of src.item and reference it with the
// this->item pointer.
//
// 2. Do not forget to copy src.quantity.
//
}
//——————————————————————————
ItemStack::~ItemStack()
{
// Every pointer must be deleted to prevent memory leaks (item is a pointer).
}
//——————————————————————————
ItemStack& ItemStack::operator=(ItemStack rhs)
{
swap(*this, rhs);
return *this;
}
//——————————————————————————
Item ItemStack::getItem() const
{
return *(this->item);
}
//——————————————————————————
int ItemStack::size() const
{
return this->quantity;
}
//——————————————————————————
void ItemStack::addItems(int a)
{
this->quantity += a;
}
//——————————————————————————
void ItemStack::addItemsFrom(const ItemStack& other)
{
this->quantity += other.quantity;
}
//——————————————————————————
bool ItemStack::operator==(const ItemStack& rhs) const
{
// Compare this and rhs for equivalence based on the ids of this->item and
// rhs.item.
return false; // replace this line
}
//——————————————————————————
bool ItemStack::operator<(const ItemStack& rhs) const { // Order (sort) this and rhs based on the ids of this->item and rhs.item.
return false; // replace this line
}
//——————————————————————————
void ItemStack::display(std::ostream& outs) const
{
outs << std::right << "(" << std::setw(2) << this->size() << ") " << (this->getItem()).getName();
}
//——————————————————————————
void swap(ItemStack& lhs, ItemStack& rhs)
{
// Swap the item data members and quantity data members for lhs and rhs.
}

Pointers/ItemStack.h
#ifndef ITEMSTACK_H_INCLUDED
#define ITEMSTACK_H_INCLUDED
#include
#include “Item.h”
using namespace std::rel_ops;
/**
* A Homogeneous–i.e., uniform–stack of Items.
*/
class ItemStack {
private:
/**
* Default Air item with id 0.
*/
static const Item DEFAULT_ITEM;
/**
* Item out of which the stack is composed.
*/
Item* item;
/**
* Number of items in the stack.
*/
int quantity;
public:
/**
* Default to an empty stack composed of Air
*/
ItemStack();
/**
* Create a stack of type *item*
*
* @param item Item out of which the stack is composed
* @param s size of the stack
*
* @pre (s > 0)
*/
ItemStack(const Item& item, int s);
// The Big-3
ItemStack(const ItemStack& src);
~ItemStack();
ItemStack& operator=(ItemStack rhs);
// End the Big-3
/**
* Retrieve the Item out of which the stack is composed
*/
Item getItem() const;
/**
* Retrieve the size of the stack
*/
int size() const;
/**
* Increase the size of the stack
*
* @param a number of items to add
* @pre a > 0
*/
void addItems(int a);
/**
* Increase the size of the stack
*
* @param other ItemStack with the items to move (i.e., steal).
*
* @pre *this.item == other.item
*/
void addItemsFrom(const ItemStack& other);
/**
* Consider two stacks to be the same if
* they contain the same type of Item.
*/
bool operator==(const ItemStack& rhs) const;
/**
* Order stacks based on Item id.
*/
bool operator<(const ItemStack& rhs) const; /** * The usual display function. */ void display(std::ostream& outs) const; /** * The usual friend-ly swap function. */ friend void swap(ItemStack& lhs, ItemStack& rhs); }; /** * Print the ItemStack using the display function. */ inline std::ostream& operator<<(std::ostream& outs, const ItemStack& prt) { prt.display(outs); return outs; } #endif Pointers/make.dep storage.o: storage.cpp Inventory.h ItemStack.h Item.h utilities.h Item.o: Item.cpp Item.h utilities.h ItemStack.o: ItemStack.cpp ItemStack.h Item.h Inventory.o: Inventory.cpp Inventory.h ItemStack.h Item.h utilities.o: utilities.cpp utilities.h Pointers/makefile MAINPROG=storage CPPS= storage.cpp Item.cpp ItemStack.cpp Inventory.cpp utilities.cpp INVENTORY_TEST_CPPS= Item.cpp ItemStack.cpp Inventory.cpp TestInventory.cpp utilities.cpp ITEMSTACK_TEST_CPPS= Item.cpp ItemStack.cpp TestItemStack.cpp utilities.cpp DIR=${PWD} ASST=$(notdir ${DIR}) ifneq (,$(findstring MinGW,$(PATH))) DISTR=MinGW EXE=.exe LFLAGS= else DISTR=Unix EXE= LFLAGS=-fsanitize=leak,address -fuse-ld=gold endif # ######################################################################## # Macro definitions for "standard" C and C++ compilations # CPPFLAGS=-g -std=c++14 -D$(DISTR) -Wall -Wextra -Wpedantic CFLAGS=-g TARGET=$(MAINPROG)$(EXE) LINK=g++ $(CPPFLAGS) # CC=gcc CPP=g++ # # # In most cases, you should not change anything below this line. # # The following is "boilerplate" to set up the standard compilation # commands: # OBJS=$(CPPS:%.cpp=%.o) DEPENDENCIES = $(CPPS:%.cpp=%.d) INVENTORY_TEST_OBJS=$(INVENTORY_TEST_CPPS:%.cpp=%.o) ITEMSTACK_TEST_OBJS=$(ITEMSTACK_TEST_CPPS:%.cpp=%.o) %.d: %.cpp touch $@ %.o: %.cpp $(CPP) $(CPPFLAGS) -MMD -o $@ -c $*.cpp # # Targets: # all: $(TARGET) tests win: $(OBJS) $(LINK) $(FLAGS) -o $(TARGET) $(OBJS) $(TARGET): $(OBJS) $(LINK) $(FLAGS) -o $(TARGET) $(OBJS) $(LFLAGS) tests: $(INVENTORY_TEST_OBJS) $(ITEMSTACK_TEST_OBJS) $(LINK) $(FLAGS) -o testInventory$(EXE) $(INVENTORY_TEST_OBJS) $(LINK) $(FLAGS) -o testItemStack$(EXE) $(ITEMSTACK_TEST_OBJS) clean: -/bin/rm -f *.d *.o $(TARGET) testInventory$(EXE) testItemStack$(EXE) make.dep: $(DEPENDENCIES) -cat $(DEPENDENCIES) > $@
include make.dep

Pointers/storage.cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include “Inventory.h”
#include “Item.h”
#include “ItemStack.h”
#include “utilities.h”
using namespace std;
/**
* Read file containing the list of all possible items.
*
* *In the next assignment this will be a generalized template function.
*
* @param inf input buffer
*
* @return collection of valid items, sorted by numeric id
*/
vector parseItemList(istream& inf);
/**
* Read inventory file and create all Inventory instances.
*
* @param items collection of valid Item entries
*
* @pre items is non-empty
*/
vector> parseInventoryFile(istream& inf,
const vector& items);
/**
* Generate a summary of all valid items
*/
void printItems(const vector& items);
/**
* Generate a summary of Inventory utilization
*/
void printInventories(const vector>& storage);
/**
* Assignment 1: Item Storage
*
* @param argv[1] items filename
* @param argv[2] inventories filename
*/
int main(int argc, char** argv)
{
// Check Command Line Arguments
if (argc != 3) {
cerr << "Usage: " << argv[0] << " list_file inventory_file" << "\n"; return 1; } ifstream infile(argv[1]); if (!infile) { cerr << "Error: " << argv[1] << " could not be opened" << "\n"; return 2; } // Read listing of possible (i.e., valid) items vector validItems = parseItemList(infile);
// Close and reset for the next file
infile.close();
infile.clear();
infile.open(argv[2]);
if (!infile) {
cout << "Error: " << argv[2] << " could not be opened" << "\n"; return 3; } vector> storage = parseInventoryFile(infile, validItems);
infile.close();
printItems(validItems);
printInventories(storage);
return 0;
}
//——————————————————————————
vector parseItemList(istream& inf)
{
vector items;
std::copy(istream_iterator(inf),
istream_iterator(),
back_inserter(items));
std::sort(items.begin(), items.end());
return items;
}
//——————————————————————————
vector> parseInventoryFile(istream& inf,
const vector& items)
{
vector> storage;
Inventory* inv = nullptr;
// First two values on a line
char leading_char;
int num_1;
cout << "Processing Log:" << "\n"; while (inf >> leading_char >> num_1) {
if (leading_char == ‘#’) {
if (inv != nullptr) {
storage.emplace_back(inv);
}
inv = new Inventory(num_1);
}
else {
int quantity;
inf >> quantity;
// Search for (key) id in list of known items
const int& key = num_1;
vector::const_iterator it;
it = std::find_if(items.begin(),
items.end(),
[key](const Item& item) -> bool
{
return item.getID() == key;
});
// Ignore any Item id not found in items
if (it != items.end()) {
ItemStack stack(*it, quantity);
const char* result = (inv->addItems(stack) ? “Stored” : “Discarded”);
cout << " " << result << " " << stack << "\n"; } } } storage.emplace_back(inv); return storage; } //------------------------------------------------------------------------------ void printItems(const vector& items)
{
cout << "\n" << "Item List:" << "\n"; for (const Item& i : items) { cout << " " << i << "\n"; } cout << "\n"; } //------------------------------------------------------------------------------ void printInventories(const vector>& storage)
{
cout << "Storage Summary:" << "\n"; for (const unique_ptr& chest : storage) {
cout << *chest << "\n"; } } Pointers/TestInventory.cpp #include
#include
#include
#include
#include
#include
#include
#include
#include “Item.h”
#include “ItemStack.h”
#include “Inventory.h”
#include “utilities.h”
#include “bodgeUnitTest.h”
//—————————————————————————–
// Inventory Unit Tests – Support Data
//—————————————————————————–
const Inventory EMPTY_INVENTORY;
const std::vector TEST_ITEMS = {
{0, “Air”},
{1, “Dirt”},
{2, “Potato”},
{3, “Makefile”},
{4, “Procrastination”}
};
//—————————————————————————–
// Inventory – Unit Tests – Test Functions
//—————————————————————————–
bool testDefaultConstructor()
{
bodgeAssert(EMPTY_INVENTORY.utilizedSlots() == 0);
bodgeAssert(EMPTY_INVENTORY.emptySlots() == 10);
bodgeAssert(EMPTY_INVENTORY.totalSlots() == 10);
bodgeAssert(!EMPTY_INVENTORY.isFull());
// I should really check display() and/or operator<< here. However, I will // do that in a seperate `testDisplay` function return true; } //----------------------------------------------------------------------------- bool testConstructorSizeN() { Inventory invWith8Slots(8); bodgeAssert(invWith8Slots.utilizedSlots() == 0); bodgeAssert(invWith8Slots.emptySlots() == 8); bodgeAssert(invWith8Slots.totalSlots() == 8); bodgeAssert(!invWith8Slots.isFull()); // I should really check display() and/or operator<< here. However, I will // do that in a seperate `testDisplay` function return true; } //----------------------------------------------------------------------------- /** * Add ItemStacks to an Inventory without filling the Inventory or attempting * to add duplicate Items */ bool testAddItemStackNoCheck() { std::vector stacksToAdd = {
{TEST_ITEMS[0], 1},
{TEST_ITEMS[1], 4},
{TEST_ITEMS[2], 8}
};
Inventory aBag(4);
aBag.addItems(stacksToAdd[0]);
aBag.addItems(stacksToAdd[1]);
aBag.addItems(stacksToAdd[2]);
bodgeAssert(!aBag.isFull());
bodgeAssert(aBag.utilizedSlots() == 3);
bodgeAssert(aBag.emptySlots() == 1);
bodgeAssert(aBag.totalSlots() == 4);
// Retrieve each of the items and check that they were added
Inventory::const_iterator it = aBag.begin();
bodgeAssert(*(it++) == stacksToAdd[0]);
bodgeAssert(*(it++) == stacksToAdd[1]);
bodgeAssert(*(it++) == stacksToAdd[2]);
// Check that there are no more ItemStacks to retrieve
bodgeAssert(it == aBag.end());
return true;
}
//—————————————————————————–
/**
* Add ItemStacks to an Inventory without filling the Inventory or attempting
* to add duplicate Items
*/
bool testAddItemWithDuplicateItems()
{
std::vector stacksToAdd = {
{TEST_ITEMS[0], 1},
{TEST_ITEMS[1], 4},
{TEST_ITEMS[1], 5}
};
Inventory aBag(4);
aBag.addItems(stacksToAdd[0]);
aBag.addItems(stacksToAdd[1]);
aBag.addItems(stacksToAdd[2]);
bodgeAssert(!aBag.isFull());
bodgeAssert(aBag.utilizedSlots() == 2);
bodgeAssert(aBag.emptySlots() == 2);
bodgeAssert(aBag.totalSlots() == 4);
// Retrieve each of the items and check that they were added
Inventory::const_iterator it = aBag.begin();
bodgeAssert(*(it++) == stacksToAdd[0]);
// Expect the merged stack to be returned.
ItemStack mergedStack(TEST_ITEMS[1], 9);
const ItemStack& retrieved = *it;
bodgeAssert(retrieved == mergedStack);
bodgeAssert(retrieved.size() == 9);
it++;
// Check that there are no more ItemStacks to retrieve
bodgeAssert(it == aBag.end());
return true;
}
//—————————————————————————–
/**
* Add ItemStacks to an Inventory and fill it.
* Then try to add one more ItemStack.
*/
bool testAddItemAfterFull()
{
std::vector stacksToAdd = {
{TEST_ITEMS[0], 1},
{TEST_ITEMS[1], 4},
{TEST_ITEMS[4], 8}
};
Inventory aBag(2);
aBag.addItems(stacksToAdd[0]);
aBag.addItems(stacksToAdd[1]);
bodgeAssert(aBag.isFull());
bodgeAssert(aBag.utilizedSlots() == 2);
bodgeAssert(aBag.emptySlots() == 0);
bodgeAssert(aBag.totalSlots() == 2);
// This add should fail
// Procrastination is bad
bodgeAssert(!(aBag.addItems(stacksToAdd[2])));
// Retrieve each of the items and check that they were added
Inventory::const_iterator it = aBag.begin();
bodgeAssert(*(it++) == stacksToAdd[0]);
bodgeAssert(*(it++) == stacksToAdd[1]);
// Check that there are no more ItemStacks to retrieve
bodgeAssert(it == aBag.end());
return true;
}
//—————————————————————————–
bool testDisplay()
{
const std::vector stacksToAdd = {
{TEST_ITEMS[0], 1},
{TEST_ITEMS[1], 4}
};
// Set up the expected strings for each ItemStack
std::vector stacksAsStrings(stacksToAdd.size());
for (unsigned int i = 0; i < stacksToAdd.size(); ++i) { stacksAsStrings[i] = toStr(stacksToAdd[i]); } // Set up the test Inventory Inventory aBag(2); aBag.addItems(stacksToAdd[0]); aBag.addItems(stacksToAdd[1]); // Check for the expected ItemStack lines within the larger output const std::string bagString = toStr(aBag); bodgeAssert(bagString.find(stacksAsStrings[0]) != std::string::npos); bodgeAssert(bagString.find(stacksAsStrings[1]) != std::string::npos); // Check for the Summary line const std::string expected = "-Used " + std::to_string(aBag.utilizedSlots()) + " of " + std::to_string(aBag.totalSlots()) + " slots"; bodgeAssert(toStr(aBag).find(expected) != std::string::npos); //-------------------------------------------------------------------------- // Check the entire output string. This should really be a seperate test //-------------------------------------------------------------------------- const std::string expectedOverall = " " + expected + "\n" + " " + stacksAsStrings[0] + "\n" + " " + stacksAsStrings[1] + "\n"; bodgeAssert(bagString == expectedOverall); return true; } //----------------------------------------------------------------------------- bool testCopyConstructorForEmpty() { Inventory aCopy(EMPTY_INVENTORY); bodgeAssert(aCopy.utilizedSlots() == 0); bodgeAssert(aCopy.emptySlots() == 10); bodgeAssert(aCopy.totalSlots() == 10); bodgeAssert(!aCopy.isFull()); // Check that both have the same data and are distinct copies bodgeAssert(aCopy == EMPTY_INVENTORY); bodgeAssert(&aCopy != &EMPTY_INVENTORY); // bodgeAssert(aCopy.begin() != EMPTY_INVENTORY.begin()); return true; } //----------------------------------------------------------------------------- bool testCopyConstructor() { const std::vector stacksToAdd = {
{TEST_ITEMS[0], 1},
{TEST_ITEMS[1], 4},
{TEST_ITEMS[4], 8}
};
Inventory source(4);
for (const ItemStack& next : stacksToAdd) {
source.addItems(next);
}
Inventory aCopy(source);
bodgeAssert(aCopy.utilizedSlots() == 3);
bodgeAssert(aCopy.emptySlots() == 1);
bodgeAssert(aCopy.totalSlots() == 4);
bodgeAssert(!aCopy.isFull());
// Check that both have the same data and are distinct copies
bodgeAssert(aCopy == source);
bodgeAssert(&aCopy != &source);
using ConstIterator = Inventory::const_iterator;
ConstIterator it = source.begin();
for (const ItemStack& nextToCheck : aCopy) {
bodgeAssert(nextToCheck == *it); // Compare ItemStacks
bodgeAssert(&nextToCheck != &(*(it++))); // Compare Memory Addresses
}
return true;
}
//—————————————————————————–
bool testAssignmentOperator()
{
const std::vector stacksToAdd = {
{TEST_ITEMS[0], 1},
{TEST_ITEMS[1], 4},
{TEST_ITEMS[4], 8}
};
Inventory source(4);
for (const ItemStack& next : stacksToAdd) {
source.addItems(next);
}
Inventory aCopy = source;
bodgeAssert(aCopy.utilizedSlots() == 3);
bodgeAssert(aCopy.emptySlots() == 1);
bodgeAssert(aCopy.totalSlots() == 4);
bodgeAssert(!aCopy.isFull());
// Check that both have the same data and are distinct copies
bodgeAssert(aCopy == source);
bodgeAssert(&aCopy != &source);
using ConstIterator = Inventory::const_iterator;
ConstIterator it = source.begin();
for (const ItemStack& nextToCheck : aCopy) {
bodgeAssert(nextToCheck == *it); // Compare ItemStacks
bodgeAssert(&nextToCheck != &(*(it++))); // Compare Memory Addresses
}
return true;
}
//—————————————————————————–
int main(int argc, char** argv)
{
UnitTestPair inventoryTests[] = {
{testDefaultConstructor, “testDefaultConstructor”},
{testConstructorSizeN, “testConstructorSizeN”},
{testAddItemStackNoCheck, “testAddItemStackNoCheck”},
{testAddItemWithDuplicateItems, “testAddItemWithDuplicateItems”},
{testAddItemAfterFull, “testAddItemAfterFull”},
{testCopyConstructorForEmpty, “testCopyConstructorForEmpty”},
{testCopyConstructor, “testCopyConstructor”},
{testAssignmentOperator, “testAssignmentOperator”},
{testDisplay, “testDisplay”},
};
std::cout << "Inventory:" << "\n"; for (const UnitTestPair& testPair : inventoryTests) { runTest(testPair.first, testPair.second); } return 0; } Pointers/TestItemStack.cpp #include
#include
#include
#include
#include
#include
#include
#include
#include “Item.h”
#include “ItemStack.h”
#include “Inventory.h”
#include “utilities.h”
#include “bodgeUnitTest.h”
//—————————————————————————–
// ItemStack Unit Tests – Support Data
//—————————————————————————–
//—————————————————————————–
// ItemStack – Unit Tests – Test Functions
//—————————————————————————–
bool testDefaultConstructor()
{
ItemStack generic;
const Item& theItem = generic.getItem();
bodgeAssert(theItem.getID() == 0);
bodgeAssert(theItem.getName() == “Air”);
bodgeAssert(generic.size() == 0);
return true;
}
bool testSecondConstructor()
{
Item aCoolItem(32, “Ice”);
ItemStack aStack(aCoolItem, 9001);
const Item& theRetrievedItem = aStack.getItem();
bodgeAssert(theRetrievedItem.getID() == 32);
bodgeAssert(theRetrievedItem.getName() == “Ice”);
bodgeAssert(aStack.size() == 9001);
return true;
}
bool testCopyConstructor()
{
Item aCoolItem(32, “More Ice”);
ItemStack originalStack(aCoolItem, 9002);
Item theRetrievedItem = originalStack.getItem();
ItemStack aCopy(originalStack);
bodgeAssert(theRetrievedItem.getID() == 32);
bodgeAssert(theRetrievedItem.getName() == “More Ice”);
bodgeAssert(originalStack.size() == 9002);
theRetrievedItem = aCopy.getItem();
bodgeAssert(theRetrievedItem.getID() == 32);
bodgeAssert(theRetrievedItem.getName() == “More Ice”);
bodgeAssert(aCopy.size() == 9002);
return true;
}
bool testAssignment()
{
Item aCoolItem(32, “Even More Ice”);
ItemStack originalStack(aCoolItem, 9002);
Item theRetrievedItem = originalStack.getItem();
ItemStack aCopy = originalStack;
bodgeAssert(theRetrievedItem.getID() == 32);
bodgeAssert(theRetrievedItem.getName() == “Even More Ice”);
bodgeAssert(originalStack.size() == 9002);
theRetrievedItem = aCopy.getItem();
bodgeAssert(theRetrievedItem.getID() == 32);
bodgeAssert(theRetrievedItem.getName() == “Even More Ice”);
bodgeAssert(aCopy.size() == 9002);
return true;
}
bool testAddItems()
{
Item aWarmItem(120, “Hot Tea”);
ItemStack aStack(aWarmItem, 12);
aStack.addItems(42);
const Item& theRetrievedItem = aStack.getItem();
bodgeAssert(theRetrievedItem.getID() == 120);
bodgeAssert(theRetrievedItem.getName() == “Hot Tea”);
bodgeAssert(aStack.size() == 54);
return true;
}
bool testAddItemsFrom()
{
Item aHotItem(200, “Mix Tape”);
ItemStack aStack(aHotItem, 12);
ItemStack aSecondStack(aHotItem, 24);
aStack.addItemsFrom(aSecondStack);
const Item& theRetrievedItem = aStack.getItem();
bodgeAssert(theRetrievedItem.getID() == 200);
bodgeAssert(theRetrievedItem.getName() == “Mix Tape”);
bodgeAssert(aStack.size() == 36);
// aSecondStack does not need to be checked due to const correctness
return true;
}
bool testLogicalEquivalence()
{
Item aJoke(42, “Emacs & PHP code”);
Item anIdenticalJoke(42, “Emacs & PHP code”);
Item anImposterJoke(42, “Code::Blocks”);
ItemStack stack1(aJoke, 9000);
ItemStack stack2(anIdenticalJoke, 337);
ItemStack stack3(anImposterJoke, 12);
// Only the Item IDs should be considered.
bodgeAssert(stack1 == stack2);
bodgeAssert(stack1 == stack3);
bodgeAssert(stack2 == stack3);
return true;
}
bool testLessThan()
{
Item aJoke(42, “Emacs & PHP code”);
Item anIdenticalJoke(42, “Emacs & PHP code”);
Item funToys(1, “Vim & Python or Rust code”);
ItemStack stack1(aJoke, 9000);
ItemStack stack2(anIdenticalJoke, 337);
ItemStack stack3(funToys, 12);
// Only the Item IDs should be considered.
bodgeAssert(!(stack1 < stack2)); bodgeAssert(!(stack2 < stack1)); // Vim should always be #1, especially if Rust & Python are involved bodgeAssert(stack3 < stack1); bodgeAssert(stack3 < stack2); return true; } bool testDisplay() { Item aWarmItem(120, "Hot Tea"); ItemStack stack1(aWarmItem, 7); const std::string expected1 = "( 7) " + aWarmItem.getName(); bodgeAssert(expected1 == toStr(stack1)); //-------------------------------------------------------------------------- Item healthyItem(99, "Celery"); ItemStack stack2(healthyItem, 42); const std::string expected2 = "(42) " + healthyItem.getName(); bodgeAssert(expected2 == toStr(stack2)); return true; } bool testSwap() { Item aWarmItem(120, "Hot Tea"); ItemStack stack1(aWarmItem, 12); Item aCoolItem(32, "Ice"); ItemStack stack2(aCoolItem, 9001); swap(stack1, stack2); bodgeAssert(stack1.getItem().getName() == "Ice"); bodgeAssert(stack1.getItem().getID() == 32); bodgeAssert(stack1.size() == 9001); bodgeAssert(stack2.getItem().getName() == "Hot Tea"); bodgeAssert(stack2.getItem().getID() == 120); bodgeAssert(stack2.size() == 12); return true; } //----------------------------------------------------------------------------- int main(int argc, char** argv) { UnitTestPair itemStackTests[] = { {testDefaultConstructor, "testDefaultConstructor"}, {testSecondConstructor, "testSecondConstructor"}, {testCopyConstructor, "testCopyConstructor"}, {testAssignment, "testAssignment"}, {testAddItems, "testAddItems"}, {testAddItemsFrom, "testAddItemsFrom"}, {testLogicalEquivalence, "testLogicalEquivalence"}, {testLessThan, "testLessThan"}, {testDisplay, "testDisplay"}, {testSwap, "testSwap"} }; std::cout << "ItemStack:" << "\n"; for (const UnitTestPair& testPair : itemStackTests) { runTest(testPair.first, testPair.second); } return 0; } Pointers/utilities.cpp #include
#include
#include “utilities.h”
/**
* Trim leading and trailing whitespace from a string.
*
* @param str string to prune
*
* @pre str is nonempty
*/
void trim(std::string& str)
{
if (str.empty()) {
return;
}
const int first_nonspace = str.find_first_not_of(” \t”);
const int last_non_space = str.find_last_not_of(” \t”);
str = str.substr(first_nonspace, last_non_space + 1);
}

Pointers/utilities.h
#ifndef UTILITIES_H_INCLUDED
#define UTILITIES_H_INCLUDED
#include
#include
/**
* Trim leading and trailing whitespace from a string.
*
* @param str string to prune
*
* @pre str is nonempty
*/
void trim(std::string& str);
/**
* Helper function for types where std::to_string is not available.
*
* Convert any type with an operator<< defined to a std::string */ template
std::string toStr(const T& thing)
{
std::ostringstream outs;
outs << thing; return outs.str(); } #endif

What Will You Get?

We provide professional writing services to help you score straight A’s by submitting custom written assignments that mirror your guidelines.

Premium Quality

Get result-oriented writing and never worry about grades anymore. We follow the highest quality standards to make sure that you get perfect assignments.

Experienced Writers

Our writers have experience in dealing with papers of every educational level. You can surely rely on the expertise of our qualified professionals.

On-Time Delivery

Your deadline is our threshold for success and we take it very seriously. We make sure you receive your papers before your predefined time.

24/7 Customer Support

Someone from our customer support team is always here to respond to your questions. So, hit us up if you have got any ambiguity or concern.

Complete Confidentiality

Sit back and relax while we help you out with writing your papers. We have an ultimate policy for keeping your personal and order-related details a secret.

Authentic Sources

We assure you that your document will be thoroughly checked for plagiarism and grammatical errors as we use highly authentic and licit sources.

Moneyback Guarantee

Still reluctant about placing an order? Our 100% Moneyback Guarantee backs you up on rare occasions where you aren’t satisfied with the writing.

Order Tracking

You don’t have to wait for an update for hours; you can track the progress of your order any time you want. We share the status after each step.

image

Areas of Expertise

Although you can leverage our expertise for any writing task, we have a knack for creating flawless papers for the following document types.

Areas of Expertise

Although you can leverage our expertise for any writing task, we have a knack for creating flawless papers for the following document types.

image

Trusted Partner of 9650+ Students for Writing

From brainstorming your paper's outline to perfecting its grammar, we perform every step carefully to make your paper worthy of A grade.

Preferred Writer

Hire your preferred writer anytime. Simply specify if you want your preferred expert to write your paper and we’ll make that happen.

Grammar Check Report

Get an elaborate and authentic grammar check report with your work to have the grammar goodness sealed in your document.

One Page Summary

You can purchase this feature if you want our writers to sum up your paper in the form of a concise and well-articulated summary.

Plagiarism Report

You don’t have to worry about plagiarism anymore. Get a plagiarism report to certify the uniqueness of your work.

Free Features $66FREE

  • Most Qualified Writer $10FREE
  • Plagiarism Scan Report $10FREE
  • Unlimited Revisions $08FREE
  • Paper Formatting $05FREE
  • Cover Page $05FREE
  • Referencing & Bibliography $10FREE
  • Dedicated User Area $08FREE
  • 24/7 Order Tracking $05FREE
  • Periodic Email Alerts $05FREE
image

Our Services

Join us for the best experience while seeking writing assistance in your college life. A good grade is all you need to boost up your academic excellence and we are all about it.

  • On-time Delivery
  • 24/7 Order Tracking
  • Access to Authentic Sources
Academic Writing

We create perfect papers according to the guidelines.

Professional Editing

We seamlessly edit out errors from your papers.

Thorough Proofreading

We thoroughly read your final draft to identify errors.

image

Delegate Your Challenging Writing Tasks to Experienced Professionals

Work with ultimate peace of mind because we ensure that your academic work is our responsibility and your grades are a top concern for us!

Check Out Our Sample Work

Dedication. Quality. Commitment. Punctuality

Categories
All samples
Essay (any type)
Essay (any type)
The Value of a Nursing Degree
Undergrad. (yrs 3-4)
Nursing
2
View this sample

It May Not Be Much, but It’s Honest Work!

Here is what we have achieved so far. These numbers are evidence that we go the extra mile to make your college journey successful.

0+

Happy Clients

0+

Words Written This Week

0+

Ongoing Orders

0%

Customer Satisfaction Rate
image

Process as Fine as Brewed Coffee

We have the most intuitive and minimalistic process so that you can easily place an order. Just follow a few steps to unlock success.

See How We Helped 9000+ Students Achieve Success

image

We Analyze Your Problem and Offer Customized Writing

We understand your guidelines first before delivering any writing service. You can discuss your writing needs and we will have them evaluated by our dedicated team.

  • Clear elicitation of your requirements.
  • Customized writing as per your needs.

We Mirror Your Guidelines to Deliver Quality Services

We write your papers in a standardized way. We complete your work in such a way that it turns out to be a perfect description of your guidelines.

  • Proactive analysis of your writing.
  • Active communication to understand requirements.
image
image

We Handle Your Writing Tasks to Ensure Excellent Grades

We promise you excellent grades and academic excellence that you always longed for. Our writers stay in touch with you via email.

  • Thorough research and analysis for every order.
  • Deliverance of reliable writing service to improve your grades.
Place an Order Start Chat Now
image

Order your essay today and save 30% with the discount code Happy