os/ossrv/genericopenlibs/cppstdlib/src/stdcpp_support.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// Name        : stdcpp_support.cpp
sl@0
    15
// Part of     : standard c++ library.
sl@0
    16
// 
sl@0
    17
//
sl@0
    18
sl@0
    19
#include <new>
sl@0
    20
#include <stdcpp_support.h>
sl@0
    21
#include <typeinfo>
sl@0
    22
#include <string>
sl@0
    23
#include <stdexcept>
sl@0
    24
sl@0
    25
sl@0
    26
EXPORT_C void TranslateSymErrorToCppException(TInt aError)
sl@0
    27
{
sl@0
    28
	switch(aError)
sl@0
    29
	{
sl@0
    30
	case KErrNoMemory:
sl@0
    31
		// This is about to use the emergency buffer!
sl@0
    32
		__THROW(std::bad_alloc());
sl@0
    33
	case KErrArgument:
sl@0
    34
		__THROW(std::invalid_argument("Invalid argument"));
sl@0
    35
	case KErrOverflow :
sl@0
    36
		__THROW(std::overflow_error("Overflow error"));
sl@0
    37
	case KErrUnderflow:
sl@0
    38
		__THROW(std::underflow_error("Underflow error"));
sl@0
    39
	default:
sl@0
    40
		__THROW(Symbian_error(KErrGeneral));
sl@0
    41
	}
sl@0
    42
}
sl@0
    43
sl@0
    44
EXPORT_C TInt TranslateCppExceptionToSymError(const std::exception& aThrow)
sl@0
    45
{
sl@0
    46
#ifndef __GCCXML__
sl@0
    47
	const std::type_info& atype = typeid(aThrow);
sl@0
    48
sl@0
    49
	if(atype == typeid (std::bad_alloc))
sl@0
    50
		return KErrNoMemory;
sl@0
    51
	else if(atype == typeid(std::invalid_argument))
sl@0
    52
		return KErrArgument;
sl@0
    53
	else if(atype == typeid(std::out_of_range))
sl@0
    54
		// std::out_of_range is of type logic_error which by definition means that it is
sl@0
    55
		// "presumably detectable before the program executes".
sl@0
    56
		// std::out_of_range is used to report an argument is not within the expected range.
sl@0
    57
		// The description of KErrArgument says an argument is out of range. Hence the mapping.
sl@0
    58
		return KErrArgument;
sl@0
    59
	else if(atype == typeid(std::overflow_error))
sl@0
    60
		return KErrOverflow;
sl@0
    61
	else if(atype == typeid(std::underflow_error))
sl@0
    62
		return KErrUnderflow;
sl@0
    63
	else
sl@0
    64
		return KErrGeneral;
sl@0
    65
#else
sl@0
    66
	return KErrGeneral;
sl@0
    67
#endif
sl@0
    68
}
sl@0
    69
sl@0
    70
#ifdef __WINSCW__
sl@0
    71
/*
sl@0
    72
 * The StdC++ global new and delete operators defined here. They are done only for the emulator
sl@0
    73
 * as for EABI platforms, it is part of the runtime support(i.e., stdnew.dll).
sl@0
    74
 */
sl@0
    75
#include <e32std.h>
sl@0
    76
sl@0
    77
EXPORT_C const std::nothrow_t std::nothrow;
sl@0
    78
sl@0
    79
EXPORT_C void* operator new(std::size_t a_size) __THROW(std::bad_alloc)
sl@0
    80
	{
sl@0
    81
	for (;;)
sl@0
    82
		{
sl@0
    83
		void* p = User::Alloc(a_size);
sl@0
    84
sl@0
    85
		if (p)
sl@0
    86
			{
sl@0
    87
			return p;
sl@0
    88
			}
sl@0
    89
		std::new_handler nh_func ;
sl@0
    90
		std::new_handler *ptr = reinterpret_cast<std::new_handler*>(Dll::Tls());
sl@0
    91
		nh_func = (ptr)?(*ptr):NULL;
sl@0
    92
sl@0
    93
		if (nh_func)
sl@0
    94
			{
sl@0
    95
			nh_func();
sl@0
    96
			}
sl@0
    97
		else
sl@0
    98
			{
sl@0
    99
			__THROW(std::bad_alloc());
sl@0
   100
			}
sl@0
   101
		}
sl@0
   102
	}
sl@0
   103
sl@0
   104
EXPORT_C void* operator new[](std::size_t a_size) __THROW(std::bad_alloc)
sl@0
   105
	{
sl@0
   106
    return ::operator new(a_size);
sl@0
   107
	}
sl@0
   108
sl@0
   109
EXPORT_C void* operator new(std::size_t a_size, const std::nothrow_t&) __NO_THROW
sl@0
   110
	{
sl@0
   111
	for (;;)
sl@0
   112
		{
sl@0
   113
		void* p = User::Alloc(a_size);
sl@0
   114
sl@0
   115
		if (p)
sl@0
   116
			{
sl@0
   117
			return p;
sl@0
   118
			}
sl@0
   119
sl@0
   120
		std::new_handler nh_func ;
sl@0
   121
		std::new_handler *ptr = reinterpret_cast<std::new_handler*>(Dll::Tls());
sl@0
   122
		nh_func = (ptr)?(*ptr):NULL;
sl@0
   123
sl@0
   124
		if (nh_func)
sl@0
   125
			{
sl@0
   126
			try
sl@0
   127
				{
sl@0
   128
				nh_func();
sl@0
   129
				}
sl@0
   130
			catch (...)
sl@0
   131
				{
sl@0
   132
				return 0;
sl@0
   133
				}
sl@0
   134
			}
sl@0
   135
		else
sl@0
   136
			{
sl@0
   137
			return 0;
sl@0
   138
			}
sl@0
   139
		}
sl@0
   140
	}
sl@0
   141
sl@0
   142
EXPORT_C void* operator new[](std::size_t a_size, const std::nothrow_t) __NO_THROW
sl@0
   143
	{
sl@0
   144
    return ::operator new(a_size, std::nothrow);
sl@0
   145
	}
sl@0
   146
sl@0
   147
// Symbian-specific addition.
sl@0
   148
EXPORT_C void* operator new(std::size_t a_size, std::size_t a_extra_size) __NO_THROW
sl@0
   149
	{
sl@0
   150
    return ::operator new(a_size + a_extra_size, std::nothrow);
sl@0
   151
	}
sl@0
   152
sl@0
   153
EXPORT_C void operator delete(void* p) __NO_THROW
sl@0
   154
	{
sl@0
   155
	User::Free(p);
sl@0
   156
	}
sl@0
   157
sl@0
   158
EXPORT_C void operator delete(void* p, const std::nothrow_t&) __NO_THROW
sl@0
   159
	{
sl@0
   160
	User::Free(p);
sl@0
   161
	}
sl@0
   162
sl@0
   163
EXPORT_C void operator delete[](void* p) __NO_THROW
sl@0
   164
	{
sl@0
   165
	User::Free(p);
sl@0
   166
	}
sl@0
   167
sl@0
   168
EXPORT_C void operator delete[](void* p, const std::nothrow_t&) __NO_THROW
sl@0
   169
	{
sl@0
   170
	User::Free(p);
sl@0
   171
	}
sl@0
   172
sl@0
   173
// Symbian-specific addition.
sl@0
   174
EXPORT_C void operator delete(void* p, std::size_t) __NO_THROW
sl@0
   175
	{
sl@0
   176
	User::Free(p);
sl@0
   177
	}
sl@0
   178
_LIT(K,"set_new_handler");
sl@0
   179
sl@0
   180
sl@0
   181
using std::new_handler;
sl@0
   182
sl@0
   183
EXPORT_C new_handler std::set_new_handler(new_handler a_new_nh) __NO_THROW
sl@0
   184
	{
sl@0
   185
	new_handler current_nh;
sl@0
   186
	TAny* tls_word_p = Dll::Tls();
sl@0
   187
sl@0
   188
	if (!tls_word_p)
sl@0
   189
		{
sl@0
   190
		// This is the first time we're called, so we need to set up the TLS.
sl@0
   191
sl@0
   192
		tls_word_p = User::Alloc( sizeof(new_handler) );
sl@0
   193
		if ( !tls_word_p )
sl@0
   194
			{
sl@0
   195
			User::Panic(K, KErrNoMemory);
sl@0
   196
			}
sl@0
   197
sl@0
   198
		Dll::SetTls(tls_word_p);
sl@0
   199
		current_nh = 0;
sl@0
   200
		}
sl@0
   201
	else
sl@0
   202
		{
sl@0
   203
		// Get the currently installed new_handler function.
sl@0
   204
		current_nh = *reinterpret_cast<new_handler*>(tls_word_p);
sl@0
   205
		}
sl@0
   206
	
sl@0
   207
	// Set the new new_handler.
sl@0
   208
	*reinterpret_cast<new_handler*>(tls_word_p) = a_new_nh;
sl@0
   209
sl@0
   210
	return current_nh;
sl@0
   211
	}
sl@0
   212
sl@0
   213
#endif //__WINSCW__