Browse Source

Replaced all usage of SLList with std::forward_list.

Fixed an infinite recursion bug in merge_sort_parallel and renamed merge_sort_internal to merge_sort_direct.
release/0.19
Jessica James 8 years ago
parent
commit
2ff758047a
  1. 30
      Jupiter/Algorithm.h
  2. 11
      Jupiter/Hash_Table.h
  3. 122
      Jupiter/Hash_Table_Imp.h
  4. 16
      Jupiter/INIConfig.cpp

30
Jupiter/Algorithm.h

@ -62,11 +62,15 @@ namespace Jupiter
*/ */
template<typename T> void merge_sort_serial(T *in_data, size_t in_data_length); template<typename T> void merge_sort_serial(T *in_data, size_t in_data_length);
/** Internal helper templates */ /**
namespace Internal * @brief Sorts an array of data in-place using merge sort across the specified number of threads
{ *
template<typename T> void merge_sort_internal(T *in_source, size_t in_length, T *out_buffer, unsigned int unused_threads); * @param in_source Data to sort
} * @param in_length Length of the array of data to sort
* @param out_buffer Working array for sorting; must be the same size as in_source
* @param unused_threads Number of additional threads to spawn (not including the thread calling the function)
*/
template<typename T> void merge_sort_direct(T *in_source, size_t in_length, T *out_buffer, unsigned int unused_threads);
} }
} }
@ -82,7 +86,7 @@ template<typename T> void Jupiter::Algorithm::merge_sort(T *in_data, size_t in_d
template<typename T> void Jupiter::Algorithm::merge_sort_parallel(T *in_data, size_t in_data_length) template<typename T> void Jupiter::Algorithm::merge_sort_parallel(T *in_data, size_t in_data_length)
{ {
merge_sort_parallel<T>(in_data, in_data_length); merge_sort_parallel<T>(in_data, in_data_length, std::thread::hardware_concurrency());
} }
template<typename T> void Jupiter::Algorithm::merge_sort_parallel(T *in_data, size_t in_data_length, unsigned int in_max_threads, bool in_force_max_threads) template<typename T> void Jupiter::Algorithm::merge_sort_parallel(T *in_data, size_t in_data_length, unsigned int in_max_threads, bool in_force_max_threads)
@ -107,7 +111,7 @@ template<typename T> void Jupiter::Algorithm::merge_sort_parallel(T *in_data, si
buffer[index] = in_data[index]; buffer[index] = in_data[index];
// mergesort into buffer // mergesort into buffer
Internal::merge_sort_internal<T>(in_data, in_data_length, buffer, thread_count - 1); merge_sort_direct<T>(in_data, in_data_length, buffer, thread_count - 1);
// mergesort is complete; free buffer // mergesort is complete; free buffer
delete[] buffer; delete[] buffer;
@ -125,7 +129,7 @@ template<typename T> void Jupiter::Algorithm::merge_sort_serial(T *in_data, size
buffer[index] = in_data[index]; buffer[index] = in_data[index];
// mergesort into buffer // mergesort into buffer
Internal::merge_sort_internal<T>(in_data, in_data_length, buffer, 0); merge_sort_direct<T>(in_data, in_data_length, buffer, 0);
// mergesort is complete; free buffer // mergesort is complete; free buffer
delete[] buffer; delete[] buffer;
@ -133,7 +137,7 @@ template<typename T> void Jupiter::Algorithm::merge_sort_serial(T *in_data, size
/** Internals */ /** Internals */
template<typename T> void Jupiter::Algorithm::Internal::merge_sort_internal(T *in_source, size_t in_length, T *out_buffer, unsigned int unused_threads) template<typename T> void Jupiter::Algorithm::merge_sort_direct(T *in_source, size_t in_length, T *out_buffer, unsigned int unused_threads)
{ {
if (in_length <= 1) // Nothing to sort if (in_length <= 1) // Nothing to sort
return; return;
@ -149,10 +153,10 @@ template<typename T> void Jupiter::Algorithm::Internal::merge_sort_internal(T *i
if (unused_threads == 0) // serial if (unused_threads == 0) // serial
{ {
// sort left // sort left
merge_sort_internal<T>(left_buffer, left_length, in_source, 0); merge_sort_direct<T>(left_buffer, left_length, in_source, 0);
// sort right // sort right
merge_sort_internal<T>(right_buffer, right_length, in_source + left_length, 0); merge_sort_direct<T>(right_buffer, right_length, in_source + left_length, 0);
} }
else // parallel else // parallel
{ {
@ -161,10 +165,10 @@ template<typename T> void Jupiter::Algorithm::Internal::merge_sort_internal(T *i
unsigned int left_thread_count = unused_threads / 2; unsigned int left_thread_count = unused_threads / 2;
// sort left // sort left
std::thread left_sort_thread(merge_sort_internal<T>, left_buffer, left_length, in_source, left_thread_count); std::thread left_sort_thread(merge_sort_direct<T>, left_buffer, left_length, in_source, left_thread_count);
// sort right // sort right
merge_sort_internal<T>(right_buffer, right_length, in_source + left_length, unused_threads - left_thread_count); merge_sort_direct<T>(right_buffer, right_length, in_source + left_length, unused_threads - left_thread_count);
left_sort_thread.join(); left_sort_thread.join();
} }

11
Jupiter/Hash_Table.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2016 Jessica James. * Copyright (C) 2016-2017 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -24,8 +24,8 @@
* @brief Defines a generic hash table structure * @brief Defines a generic hash table structure
*/ */
#include <forward_list>
#include "String.h" #include "String.h"
#include "SLList.h"
namespace Jupiter namespace Jupiter
{ {
@ -69,7 +69,8 @@ namespace Jupiter
* @param in_key Key of the entry to search for * @param in_key Key of the entry to search for
* @return Pointer to the value of the entry if it exists, nullptr otherwise * @return Pointer to the value of the entry if it exists, nullptr otherwise
*/ */
ValueT *get(const InKeyT &in_key) const; const ValueT *get(const InKeyT &in_key) const;
ValueT *get(const InKeyT &in_key);
const InValueT &get(const InKeyT &in_key, const InValueT &in_value) const; const InValueT &get(const InKeyT &in_key, const InValueT &in_value) const;
template<typename CastT> CastT getCast(const InKeyT &in_key, const CastT &in_value) const; template<typename CastT> CastT getCast(const InKeyT &in_key, const CastT &in_value) const;
@ -99,6 +100,7 @@ namespace Jupiter
* @param in_callback Function to callback * @param in_callback Function to callback
*/ */
template<typename CallT> void callback(CallT &in_callback) const; template<typename CallT> void callback(CallT &in_callback) const;
template<typename CallT> void callback(CallT &in_callback);
/** /**
* @brief Copy assignment operator * @brief Copy assignment operator
@ -137,7 +139,7 @@ namespace Jupiter
~Bucket(); ~Bucket();
/** List of entries in the bucket */ /** List of entries in the bucket */
Jupiter::SLList<Entry> m_entries; std::forward_list<Entry> m_entries;
}; };
/** /**
@ -190,6 +192,7 @@ namespace Jupiter
* @param in_callback Function to callback * @param in_callback Function to callback
*/ */
template<typename CallT> void callback(CallT &in_callback) const; template<typename CallT> void callback(CallT &in_callback) const;
template<typename CallT> void callback(CallT &in_callback);
/** /**
* @brief Returns the number of entries in the table * @brief Returns the number of entries in the table

122
Jupiter/Hash_Table_Imp.h

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2016 Jessica James. * Copyright (C) 2016-2017 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -69,11 +69,21 @@ Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::Entry::Entry
/** Hash_Table::Bucket */ /** Hash_Table::Bucket */
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
ValueT *Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::get(const InKeyT &in_key) const const ValueT *Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::get(const InKeyT &in_key) const
{ {
for (Jupiter::SLList<Entry>::Node *node = m_entries.getHead(); node != nullptr; node = node->next) for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
if (node->data->key == in_key) if (node->key == in_key)
return &node->data->value; return &node->value;
return nullptr;
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
ValueT *Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::get(const InKeyT &in_key)
{
for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
if (node->key == in_key)
return &node->value;
return nullptr; return nullptr;
} }
@ -81,9 +91,9 @@ ValueT *Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::get(
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
const InValueT &Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::get(const InKeyT &in_key, const InValueT &in_value) const const InValueT &Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::get(const InKeyT &in_key, const InValueT &in_value) const
{ {
for (Jupiter::SLList<Entry>::Node *node = m_entries.getHead(); node != nullptr; node = node->next) for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
if (node->data->key == in_key) if (node->key == in_key)
return node->data->value; return node->value;
return in_value; return in_value;
} }
@ -92,9 +102,9 @@ template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, siz
template<typename CastT> template<typename CastT>
CastT Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::getCast(const InKeyT &in_key, const CastT &in_value) const CastT Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::getCast(const InKeyT &in_key, const CastT &in_value) const
{ {
for (Jupiter::SLList<Entry>::Node *node = m_entries.getHead(); node != nullptr; node = node->next) for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
if (node->data->key == in_key) if (node->key == in_key)
return static_cast<CastT>(node->data->value); return static_cast<CastT>(node->value);
return in_value; return in_value;
} }
@ -102,54 +112,60 @@ CastT Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::getCas
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
bool Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::set(const InKeyT &in_key, const InValueT &in_value) bool Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::set(const InKeyT &in_key, const InValueT &in_value)
{ {
for (Jupiter::SLList<Entry>::Node *node = m_entries.getHead(); node != nullptr; node = node->next) for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
if (node->data->key == in_key) if (node->key == in_key)
{ {
node->data->value = in_value; node->value = in_value;
return false; return false;
} }
m_entries.add(new Entry(in_key, in_value)); m_entries.emplace_front(in_key, in_value);
return true; return true;
} }
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
bool Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::set(const InKeyT &in_key) bool Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::set(const InKeyT &in_key)
{ {
for (Jupiter::SLList<Entry>::Node *node = m_entries.getHead(); node != nullptr; node = node->next) for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
if (node->data->key == in_key) if (node->key == in_key)
return false; return false;
m_entries.add(new Entry(in_key)); m_entries.emplace_front(in_key);
return true; return true;
} }
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
bool Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::remove(const InKeyT &in_key) bool Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::remove(const InKeyT &in_key)
{ {
Jupiter::SLList<Entry>::Node *node = m_entries.getHead(); auto node = m_entries.begin();
auto end = m_entries.end();
// No nodes in the bucket // No nodes in the bucket
if (node == nullptr) if (node == end)
return false; return false;
// Check if the head is the desired node // Check if the head is the desired node
if (node->data->key == in_key) if (node->key == in_key)
{ {
delete m_entries.removeHead(); m_entries.pop_front();
return true; return true;
} }
auto next_node = node;
++next_node;
// iterate through list // iterate through list
while (node->next != nullptr) while (next_node != end)
{ {
if (node->next->data->key == in_key) if (next_node->key == in_key)
{ {
// The next node is the desired node // The next node is the desired node
delete m_entries.removeNext(node); m_entries.erase_after(node);
return true; return true;
} }
node = node->next;
node = next_node;
++next_node;
} }
return false; return false;
@ -159,16 +175,24 @@ template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, siz
template<typename CallT> template<typename CallT>
void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::callback(CallT &in_callback) const void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::callback(CallT &in_callback) const
{ {
for (Jupiter::SLList<Entry>::Node *node = m_entries.getHead(); node != nullptr; node = node->next) for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
in_callback(*node->data); in_callback(*node);
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
template<typename CallT>
void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::callback(CallT &in_callback)
{
for (auto node = m_entries.begin(); node != m_entries.end(); ++node)
in_callback(*node);
} }
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
typename Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket &Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::operator=(const Bucket &in_bucket) typename Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket &Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::operator=(const Bucket &in_bucket)
{ {
m_entries.eraseAndDelete(); m_entries.clear();
for (Jupiter::SLList<Entry>::Node *node = in_bucket.m_entries.getHead(); node != nullptr; node = node->next) for (auto node = in_bucket.m_entries.begin(); node != m_entries.end(); ++node)
m_entries.add(new Entry(node->data->key, node->data->value)); m_entries.emplace_front(node->key, node->value);
return *this; return *this;
} }
@ -183,8 +207,8 @@ typename Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket &Jup
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::Bucket(const Bucket &in_bucket) Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::Bucket(const Bucket &in_bucket)
{ {
for (Jupiter::SLList<Entry>::Node *node = in_bucket.m_entries.getHead(); node != nullptr; node = node->next) for (auto node = in_bucket.m_entries.getHead(); node != in_bucket.m_entries.end(); ++node)
m_entries.add(new Entry(node->data->key, node->data->value)); m_entries.emplace_front(node->key, node->value);
} }
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
@ -196,7 +220,7 @@ Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::Bucket(Bucke
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::~Bucket() Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::Bucket::~Bucket()
{ {
m_entries.eraseAndDelete(); m_entries.clear();
} }
/** Hash_Table */ /** Hash_Table */
@ -286,6 +310,20 @@ void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::callback(CallT
} }
} }
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
template<typename CallT>
void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::callback(CallT &in_callback)
{
Bucket *itr = m_buckets;
Bucket *end = m_buckets + m_buckets_size;
while (itr != end)
{
itr->callback<CallT>(in_callback);
++itr;
}
}
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
size_t Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::size() const size_t Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::size() const
{ {
@ -327,22 +365,22 @@ typename Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF> &Jupiter::Ha
else else
{ {
// we need to erase data; slightly modified version of copy_to_buckets() // we need to erase data; slightly modified version of copy_to_buckets()
Jupiter::SLList<Bucket::Entry>::Node *node; std::forward_list<Bucket::Entry>::iterator node;
size_t index = 0; size_t index = 0;
while (index != in_table.m_buckets_size) while (index != in_table.m_buckets_size)
{ {
in_table.m_buckets[index].m_entries.eraseAndDelete(); in_table.m_buckets[index].m_entries.clear();
for (node = in_table.m_buckets[index].m_entries.getHead(); node != nullptr; node = node->next) for (node = in_table.m_buckets[index].m_entries.begin(); node != in_table.m_buckets[index].m_entries.end(); ++node)
m_buckets[HashF(node->data->key) % m_buckets_size].set(node->data->key, node->data->value); m_buckets[HashF(node->key) % m_buckets_size].set(node->key, node->value);
++index; ++index;
} }
while (index != m_buckets_size) while (index != m_buckets_size)
{ {
in_table.m_buckets[index].m_entries.eraseAndDelete(); in_table.m_buckets[index].m_entries.clear();
++index; ++index;
} }
} }
@ -460,11 +498,11 @@ void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::expand()
template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)> template<typename KeyT, typename ValueT, typename InKeyT, typename InValueT, size_t(*HashF)(const InKeyT &)>
void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::copy_to_buckets(Bucket *in_buckets, size_t in_buckets_size) const void Jupiter::Hash_Table<KeyT, ValueT, InKeyT, InValueT, HashF>::copy_to_buckets(Bucket *in_buckets, size_t in_buckets_size) const
{ {
Jupiter::SLList<Bucket::Entry>::Node *node; std::forward_list<Bucket::Entry>::iterator node;
for (size_t index = 0; index != m_buckets_size; ++index) for (size_t index = 0; index != m_buckets_size; ++index)
for (node = m_buckets[index].m_entries.getHead(); node != nullptr; node = node->next) for (node = m_buckets[index].m_entries.begin(); node != m_buckets[index].m_entries.end(); ++node)
in_buckets[HashF(node->data->key) % in_buckets_size].set(node->data->key, node->data->value); in_buckets[HashF(node->key) % in_buckets_size].set(node->key, node->value);
} }
#endif // _HASH_TABLE_IMP_H_HEADER #endif // _HASH_TABLE_IMP_H_HEADER

16
Jupiter/INIConfig.cpp

@ -1,5 +1,5 @@
/** /**
* Copyright (C) 2016 Jessica James. * Copyright (C) 2016-2017 Jessica James.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -49,20 +49,20 @@ void Jupiter::INIConfig::write_helper(FILE *in_file, const Jupiter::Config *in_s
{ {
auto bucket_itr = in_section->getTable().begin(); auto bucket_itr = in_section->getTable().begin();
auto bucket_end = in_section->getTable().end(); auto bucket_end = in_section->getTable().end();
Jupiter::SLList<HashTable::Bucket::Entry>::Node *entry_itr; std::forward_list<HashTable::Bucket::Entry>::iterator entry_itr;
while (bucket_itr != bucket_end) while (bucket_itr != bucket_end)
{ {
for (entry_itr = bucket_itr->m_entries.getHead(); entry_itr != nullptr; entry_itr = entry_itr->next) for (entry_itr = bucket_itr->m_entries.begin(); entry_itr != bucket_itr->m_entries.end(); ++entry_itr)
{ {
// Tabs // Tabs
for (index = 1; index < in_depth; ++index) for (index = 1; index < in_depth; ++index)
fputc('\t', in_file); fputc('\t', in_file);
// Write entry // Write entry
entry_itr->data->key.print(in_file); entry_itr->key.print(in_file);
fputs(" = ", in_file); fputs(" = ", in_file);
entry_itr->data->value.println(in_file); entry_itr->value.println(in_file);
} }
++bucket_itr; ++bucket_itr;
@ -73,12 +73,12 @@ void Jupiter::INIConfig::write_helper(FILE *in_file, const Jupiter::Config *in_s
{ {
auto bucket_itr = in_section->getSections().begin(); auto bucket_itr = in_section->getSections().begin();
auto bucket_end = in_section->getSections().end(); auto bucket_end = in_section->getSections().end();
Jupiter::SLList<SectionHashTable::Bucket::Entry>::Node *entry_itr; std::forward_list<SectionHashTable::Bucket::Entry>::iterator entry_itr;
while (bucket_itr != bucket_end) while (bucket_itr != bucket_end)
{ {
for (entry_itr = bucket_itr->m_entries.getHead(); entry_itr != nullptr; entry_itr = entry_itr->next) for (entry_itr = bucket_itr->m_entries.begin(); entry_itr != bucket_itr->m_entries.end(); ++entry_itr)
write_helper(in_file, &entry_itr->data->value, in_depth + 1); write_helper(in_file, &entry_itr->value, in_depth + 1);
++bucket_itr; ++bucket_itr;
} }

Loading…
Cancel
Save