Mybowlcut
June 21st, 2008, 03:20 AM
Hey. I've got a weird problem... I've been building my program in release mode just recently and I've come across a problem where a string is inserted into a vector... the highlighted code shows the line where the problem is.
The string is fine until it's pushed into the vector... after it's pushed in, the vector still has 0 elements... I stepped into the push_back definition and the parameter _Val was <Bad Ptr>...
I have no clue why it's happening... here is the relevant code:/*
Universal class. Edits affect multiple projects.
*/
#ifndef XSCREEN_H
#define XSCREEN_H
//testing
#include <iostream>
#include <algorithm>
#include <functional>
#include <string>
#include <exception>
#include "Base_XImage.h"
#include "Clone_Back_Insert_Iterator.h"
#include "Cloneable.h"
#include "Drawable.h"
#include "IO.h"
#include "Uncopyable.h"
// Type used to mark the end of a typelist.
struct Null_Type
{
};
// The typelist. For nested typelists type U is a typelist again, so one can
// build typelists of any length.
template<typename T, typename U>
struct Type_List
{
typedef T head;
typedef U tail;
};
// Convenience macros for building typelists.
#define TL1(T1) Type_List<T1, Null_Type >
#define TL2(T1,T2) Type_List<T1, TL1(T2) >
#define TL3(T1,T2,T3) Type_List<T1, TL2(T2,T3) >
#define TL4(T1,T2,T3,T4) Type_List<T1, TL3(T2,T3,T4) >
#define TL5(T1,T2,T3,T4,T5) Type_List<T1, TL4(T2,T3,T4,T5) >
#define TL6(T1,T2,T3,T4,T5,T6) Type_List<T1, TL5(T2,T3,T4,T5,T6) >
#define TL7(T1,T2,T3,T4,T5,T6,T7) Type_List<T1, TL6(T2,T3,T4,T5,T6,T7) >
#define TL8(T1,T2,T3,T4,T5,T6,T7,T8) Type_List<T1, TL7(T2,T3,T4,T5,T6,T7,T8) >
#define TL9(T1,T2,T3,T4,T5,T6,T7,T8,T9) Type_List<T1, TL8(T2,T3,T4,T5,T6,T7,T8,T9) >
#define TL10(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10) Type_List<T1, TL9(T2,T3,T4,T5,T6,T7,T8,T9,T10) >
/*
To use this class, pass in a typelist (e.g):
#define MY_TYPE_LIST TL3(XImage, XButton, Class_Derived_From_Base_XImage)
Order matters... in this case XImage then XButton then Class_Der[..] will be
updated and drawn in sequential order.
*/
template<typename Type_List>
class XScreen : public Drawable, public Updateable, public Uncopyable
{
public:
XScreen() {}
XScreen(const std::string& directory)
:
directory(directory)
{
Load<Type_List>();
}
virtual ~XScreen()
{
for(std::vector<Base_XImage*>::iterator it = elements.begin();
it != elements.end(); ++it)
{
delete *it;
}
}
virtual void Draw()
{
std::for_each(
elements.begin(),
elements.end(),
std::mem_fun(&Base_XImage::Draw));
}
virtual void Update(const SDL_Event& event_)
{
std::vector<Base_XImage*>::iterator it = elements.begin();
for(; it != elements.end(); ++it)
{
(*it)->Update(event_);
}
}
protected:
template<typename Type_List>
void Load()
{
// Get the name of the type of each element.
Get_Element_Types<Type_List>();
// Recursively load each type of element from respective file.
Load_Elements<Type_List>();
}
template<typename Type_List>
void Get_Element_Types()
{
// element_types.push_back(Remove_Class_Prefix(typeid(Type_List::head).name()));
// testing
std::string s = Remove_Class_Prefix(typeid(Type_List::head).name());
std::cout << s;
element_types.push_back(s);
// testing
// Recursive call when tail is NOT Null_Type.
Get_Element_Types<Type_List::tail>();
}
// Specialized template function to end typelist traversion(recursion).
template<>
void Get_Element_Types<Null_Type>()
{
}
static std::string XScreen::Remove_Class_Prefix(std::string s)
{
const int PREFIX_LENGTH = 6;
if(s.size() <= PREFIX_LENGTH)
{ // Too small.
throw std::runtime_error("Missing class prefix in Remove_Class_Prefix: " + s);
}
s.erase(s.begin(), s.begin() + 6);
return s;
}
template<typename T>
std::string Get_Element_File_Name()
{
return Remove_Class_Prefix(std::string(typeid(T).name()) + "s.txt");
}
template<typename T>
bool Valid_Element_Class()
{
for(std::vector<std::string>::const_iterator it = element_types.begin();
it != element_types.end(); ++it)
{
if(Remove_Class_Prefix(typeid(T).name()) == *it)
{
return true;
}
}
return false;
}
template<typename T>
void Load_Elements_Of_Type()
{
if(!Valid_Element_Class<T>())
{ // Not a valid element.
throw std::runtime_error("Load_Elements_Of_Type: " +
std::string(typeid(T).name()) + "is not a valid element type.");
}
try
{
std::ifstream file;
IO::open_read_file(file, directory + Get_Element_File_Name<T>());
IO::read_data_clone<T, std::vector<Base_XImage*> >(elements, file);
file.close();
}
catch(const std::runtime_error r)
{ // No file; don't want to load element type "T".
}
}
// The load function. Its template parameter is a typelist which is traversed
// from head to tail. A specialized template function for Null_Type ends the
// recursion.
template<typename Type_List>
void Load_Elements()
{
Load_Elements_Of_Type<Type_List::head>();
// Recursive call when tail is NOT Null_Type.
Load_Elements<Type_List::tail>();
}
// Specialized template function to end typelist traversion(recursion).
template<>
void Load_Elements<Null_Type>()
{
}
protected:
std::vector<std::string> element_types;
std::vector<Base_XImage*> elements;
std::string directory;
};
#endif
Cheers.
The string is fine until it's pushed into the vector... after it's pushed in, the vector still has 0 elements... I stepped into the push_back definition and the parameter _Val was <Bad Ptr>...
I have no clue why it's happening... here is the relevant code:/*
Universal class. Edits affect multiple projects.
*/
#ifndef XSCREEN_H
#define XSCREEN_H
//testing
#include <iostream>
#include <algorithm>
#include <functional>
#include <string>
#include <exception>
#include "Base_XImage.h"
#include "Clone_Back_Insert_Iterator.h"
#include "Cloneable.h"
#include "Drawable.h"
#include "IO.h"
#include "Uncopyable.h"
// Type used to mark the end of a typelist.
struct Null_Type
{
};
// The typelist. For nested typelists type U is a typelist again, so one can
// build typelists of any length.
template<typename T, typename U>
struct Type_List
{
typedef T head;
typedef U tail;
};
// Convenience macros for building typelists.
#define TL1(T1) Type_List<T1, Null_Type >
#define TL2(T1,T2) Type_List<T1, TL1(T2) >
#define TL3(T1,T2,T3) Type_List<T1, TL2(T2,T3) >
#define TL4(T1,T2,T3,T4) Type_List<T1, TL3(T2,T3,T4) >
#define TL5(T1,T2,T3,T4,T5) Type_List<T1, TL4(T2,T3,T4,T5) >
#define TL6(T1,T2,T3,T4,T5,T6) Type_List<T1, TL5(T2,T3,T4,T5,T6) >
#define TL7(T1,T2,T3,T4,T5,T6,T7) Type_List<T1, TL6(T2,T3,T4,T5,T6,T7) >
#define TL8(T1,T2,T3,T4,T5,T6,T7,T8) Type_List<T1, TL7(T2,T3,T4,T5,T6,T7,T8) >
#define TL9(T1,T2,T3,T4,T5,T6,T7,T8,T9) Type_List<T1, TL8(T2,T3,T4,T5,T6,T7,T8,T9) >
#define TL10(T1,T2,T3,T4,T5,T6,T7,T8,T9,T10) Type_List<T1, TL9(T2,T3,T4,T5,T6,T7,T8,T9,T10) >
/*
To use this class, pass in a typelist (e.g):
#define MY_TYPE_LIST TL3(XImage, XButton, Class_Derived_From_Base_XImage)
Order matters... in this case XImage then XButton then Class_Der[..] will be
updated and drawn in sequential order.
*/
template<typename Type_List>
class XScreen : public Drawable, public Updateable, public Uncopyable
{
public:
XScreen() {}
XScreen(const std::string& directory)
:
directory(directory)
{
Load<Type_List>();
}
virtual ~XScreen()
{
for(std::vector<Base_XImage*>::iterator it = elements.begin();
it != elements.end(); ++it)
{
delete *it;
}
}
virtual void Draw()
{
std::for_each(
elements.begin(),
elements.end(),
std::mem_fun(&Base_XImage::Draw));
}
virtual void Update(const SDL_Event& event_)
{
std::vector<Base_XImage*>::iterator it = elements.begin();
for(; it != elements.end(); ++it)
{
(*it)->Update(event_);
}
}
protected:
template<typename Type_List>
void Load()
{
// Get the name of the type of each element.
Get_Element_Types<Type_List>();
// Recursively load each type of element from respective file.
Load_Elements<Type_List>();
}
template<typename Type_List>
void Get_Element_Types()
{
// element_types.push_back(Remove_Class_Prefix(typeid(Type_List::head).name()));
// testing
std::string s = Remove_Class_Prefix(typeid(Type_List::head).name());
std::cout << s;
element_types.push_back(s);
// testing
// Recursive call when tail is NOT Null_Type.
Get_Element_Types<Type_List::tail>();
}
// Specialized template function to end typelist traversion(recursion).
template<>
void Get_Element_Types<Null_Type>()
{
}
static std::string XScreen::Remove_Class_Prefix(std::string s)
{
const int PREFIX_LENGTH = 6;
if(s.size() <= PREFIX_LENGTH)
{ // Too small.
throw std::runtime_error("Missing class prefix in Remove_Class_Prefix: " + s);
}
s.erase(s.begin(), s.begin() + 6);
return s;
}
template<typename T>
std::string Get_Element_File_Name()
{
return Remove_Class_Prefix(std::string(typeid(T).name()) + "s.txt");
}
template<typename T>
bool Valid_Element_Class()
{
for(std::vector<std::string>::const_iterator it = element_types.begin();
it != element_types.end(); ++it)
{
if(Remove_Class_Prefix(typeid(T).name()) == *it)
{
return true;
}
}
return false;
}
template<typename T>
void Load_Elements_Of_Type()
{
if(!Valid_Element_Class<T>())
{ // Not a valid element.
throw std::runtime_error("Load_Elements_Of_Type: " +
std::string(typeid(T).name()) + "is not a valid element type.");
}
try
{
std::ifstream file;
IO::open_read_file(file, directory + Get_Element_File_Name<T>());
IO::read_data_clone<T, std::vector<Base_XImage*> >(elements, file);
file.close();
}
catch(const std::runtime_error r)
{ // No file; don't want to load element type "T".
}
}
// The load function. Its template parameter is a typelist which is traversed
// from head to tail. A specialized template function for Null_Type ends the
// recursion.
template<typename Type_List>
void Load_Elements()
{
Load_Elements_Of_Type<Type_List::head>();
// Recursive call when tail is NOT Null_Type.
Load_Elements<Type_List::tail>();
}
// Specialized template function to end typelist traversion(recursion).
template<>
void Load_Elements<Null_Type>()
{
}
protected:
std::vector<std::string> element_types;
std::vector<Base_XImage*> elements;
std::string directory;
};
#endif
Cheers.