#ifndef FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_
#define FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_


template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(key_t key, T value, Iterator *storedValue) {
	if (_size == theMap.maxSize()) {
		return MAP_FULL;
	}
	size_t position = findNicePlace(key);
	memmove(static_cast<void*>(&theMap[position + 1]),static_cast<void*>(&theMap[position]),
			(_size - position) * sizeof(std::pair<key_t,T>));
	theMap[position].first = key;
	theMap[position].second = value;
	++_size;
	if (storedValue != nullptr) {
		*storedValue = Iterator(&theMap[position]);
	}
	return HasReturnvaluesIF::RETURN_OK;
}
template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::insert(std::pair<key_t, T> pair) {
	return insert(pair.first, pair.second);
}

template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::exists(key_t key) const {
	ReturnValue_t result = KEY_DOES_NOT_EXIST;
	if (findFirstIndex(key) < _size) {
		result = HasReturnvaluesIF::RETURN_OK;
	}
	return result;
}

template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(Iterator *iter) {
	size_t i;
	if ((i = findFirstIndex((*iter).value->first)) >= _size) {
		return KEY_DOES_NOT_EXIST;
	}
	removeFromPosition(i);
	if (*iter != begin()) {
		(*iter)--;
	} else {
		*iter = begin();
	}
	return HasReturnvaluesIF::RETURN_OK;
}

template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::erase(key_t key) {
	size_t i;
	if ((i = findFirstIndex(key)) >= _size) {
		return KEY_DOES_NOT_EXIST;
	}
	do {
		removeFromPosition(i);
		i = findFirstIndex(key, i);
	} while (i < _size);
	return HasReturnvaluesIF::RETURN_OK;
}

template<typename key_t, typename T, typename KEY_COMPARE>
inline ReturnValue_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::find(key_t key, T **value) const {
	ReturnValue_t result = exists(key);
	if (result != HasReturnvaluesIF::RETURN_OK) {
		return result;
	}
	*value = &theMap[findFirstIndex(key)].second;
	return HasReturnvaluesIF::RETURN_OK;
}

template<typename key_t, typename T, typename KEY_COMPARE>
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findFirstIndex(key_t key, size_t startAt) const {
	if (startAt >= _size) {
		return startAt + 1;
	}
	size_t i = startAt;
	for (i = startAt; i < _size; ++i) {
		if (theMap[i].first == key) {
			return i;
		}
	}
	return i;
}

template<typename key_t, typename T, typename KEY_COMPARE>
inline size_t FixedOrderedMultimap<key_t, T, KEY_COMPARE>::findNicePlace(key_t key) const {
	size_t i = 0;
	for (i = 0; i < _size; ++i) {
		if (myComp(key, theMap[i].first)) {
			return i;
		}
	}
	return i;
}

template<typename key_t, typename T, typename KEY_COMPARE>
inline void FixedOrderedMultimap<key_t, T, KEY_COMPARE>::removeFromPosition(size_t position) {
	if (_size <= position) {
		return;
	}
	memmove(static_cast<void*>(&theMap[position]), static_cast<void*>(&theMap[position + 1]),
			(_size - position - 1) * sizeof(std::pair<key_t,T>));
	--_size;
}


#endif /* FRAMEWORK_CONTAINER_FIXEDORDEREDMULTIMAP_TPP_ */